您好,欢迎来到九壹网。
搜索
您的当前位置:首页SpringBoot之SpringBoot整合异步线程调用注解

SpringBoot之SpringBoot整合异步线程调用注解

来源:九壹网
SpringBoot之SpringBoot整合异步线程调⽤注解

SpringBoot之SpringBoot整合异步线程调⽤注解

理念:

  为了快速响应浏览器,开启多线程执⾏任务

   但是有⼀个缺点,会增加CPU资源的消耗,所以⼤的项⽬推荐使⽤MQ消息队列

编写代码:

@GetMapping(\"/addDB\") public String addDB() { // 模拟数据交互 log.info(\"<01>\"); sms();

log.info(\"<04>\");

return \"⽤户注册成功\"; }

/**

* 模拟发送短信 *

* @return */

public String sms() { log.info(\"<02>\"); try {

log.info(\"正在发送短信...\"); Thread.sleep(3000);

} catch (InterruptedException e) { e.printStackTrace(); }

return \"短信发送完成\"; }

这个接⼝最少需要4秒才能返回,如果发送短信时间更长,返回时间增加,这样⽤户的体验就⾮常不好

启动项⽬测试

他是单线程去执⾏的,看过Tomcat的应该也知道,tomcat会为每⼀次请求从他的线程池中单独拿⼀个线程去执⾏,所以它是单线程 的所以这⾥就可以使⽤Spring提供的异步注解

异步注解的使⽤:

在⽅法上添加@Async注解

并且在启动类中开启异步注解

启动测试:

不对呀,这还是单线程呀

异步注解失效问题解决:

需要把sms⽅法单独提取成⼀个类

package com.springboot.demo.async;

import lombok.extern.slf4j.Slf4j;

import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Component;/**

* @author ZYGisComputer */

@Slf4j

@Component

public class SmsService {

/**

* 模拟发送短信 *

* @return */

@Async

public String sms() { log.info(\"<02>\"); try {

log.info(\"正在发送短信...\"); Thread.sleep(3000);

} catch (InterruptedException e) { e.printStackTrace(); }

return \"短信发送完成\"; } }

通过Autowirld的⽅式注⼊使⽤

再次测试

可以看到执⾏成功了,并且也是不同的线程,但是他这样都是每次都是new⼀个新的线程,这显然是不合理的,因为使⽤线程就应该考虑采⽤线程池

异步注解整合线程池:

创建config包,并在下⾯创建ThreadPoolConfig.java

package com.springboot.demo.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;import org.springframework.core.task.TaskExecutor;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.ThreadPoolExecutor;@Configuration@EnableAsync

public class ThreadPoolConfig { /**

* 每秒需要多少个线程处理? * tasks/(1/taskcost) */

private int corePoolSize = 3;

/**

* 线程池维护线程的最⼤数量

* (max(tasks)- queueCapacity)/(1/taskcost) */

private int maxPoolSize = 3;

/**

* 缓存队列

* (coreSizePool/taskcost)*responsetime

*/

private int queueCapacity = 10; /**

* 允许的空闲时间 * 默认为60 */

private int keepAlive = 100;

@Bean

public TaskExecutor taskExecutor() {

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核⼼线程数

executor.setCorePoolSize(corePoolSize); // 设置最⼤线程数

executor.setMaxPoolSize(maxPoolSize); // 设置队列容量

executor.setQueueCapacity(queueCapacity); // 设置允许的空闲时间(秒)

//executor.setKeepAliveSeconds(keepAlive); // 设置默认线程名称

executor.setThreadNamePrefix(\"thread-\");

// 设置拒绝策略rejection-policy:当pool已经达到max size的时候,如何处理新任务 // CALLER_RUNS:不在新线程中执⾏任务,⽽是有调⽤者所在的线程来执⾏

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 等待所有任务结束后再关闭线程池

executor.setWaitForTasksToCompleteOnShutdown(true); return executor; }}

在@Async注解中配置线程池名称就可以

启动项⽬测试:

2021-01-26 18:18:53,820 [http-nio-8082-exec-1] INFO (HelloService.java:76)- <01>2021-01-26 18:18:53,823 [http-nio-8082-exec-1] INFO (HelloService.java:78)- <04>

2021-01-26 18:18:53,823 [http-nio-8082-exec-1] INFO (LogAspect.java:50)- RESPONSE : ⽤户注册成功2021-01-26 18:18:53,829 [thread-1] INFO (SmsService.java:24)- <02>

2021-01-26 18:18:53,831 [thread-1] INFO (SmsService.java:26)- 正在发送短信...<执⾏定时任务>:18:18:56<执⾏定时任务>:18:19:01

2021-01-26 18:19:01,340 [http-nio-8082-exec-3] INFO (LogAspect.java:37)- URL : http://localhost:8082/addDB2021-01-26 18:19:01,341 [http-nio-8082-exec-3] INFO (LogAspect.java:38)- HTTP_METHOD : GET2021-01-26 18:19:01,341 [http-nio-8082-exec-3] INFO (LogAspect.java:39)- IP : 0:0:0:0:0:0:0:12021-01-26 18:19:01,341 [http-nio-8082-exec-3] INFO (HelloService.java:76)- <01>2021-01-26 18:19:01,342 [http-nio-8082-exec-3] INFO (HelloService.java:78)- <04>2021-01-26 18:19:01,342 [thread-2] INFO (SmsService.java:24)- <02>

2021-01-26 18:19:01,342 [thread-2] INFO (SmsService.java:26)- 正在发送短信...

2021-01-26 18:19:01,342 [http-nio-8082-exec-3] INFO (LogAspect.java:50)- RESPONSE : ⽤户注册成功

2021-01-26 18:19:01,922 [http-nio-8082-exec-4] INFO (LogAspect.java:37)- URL : http://localhost:8082/addDB2021-01-26 18:19:01,922 [http-nio-8082-exec-4] INFO (LogAspect.java:38)- HTTP_METHOD : GET2021-01-26 18:19:01,923 [http-nio-8082-exec-4] INFO (LogAspect.java:39)- IP : 0:0:0:0:0:0:0:12021-01-26 18:19:01,923 [http-nio-8082-exec-4] INFO (HelloService.java:76)- <01>2021-01-26 18:19:01,923 [http-nio-8082-exec-4] INFO (HelloService.java:78)- <04>2021-01-26 18:19:01,924 [thread-3] INFO (SmsService.java:24)- <02>

2021-01-26 18:19:01,924 [http-nio-8082-exec-4] INFO (LogAspect.java:50)- RESPONSE : ⽤户注册成功2021-01-26 18:19:01,924 [thread-3] INFO (SmsService.java:26)- 正在发送短信...

2021-01-26 18:19:02,559 [http-nio-8082-exec-2] INFO (LogAspect.java:37)- URL : http://localhost:8082/addDB2021-01-26 18:19:02,559 [http-nio-8082-exec-2] INFO (LogAspect.java:38)- HTTP_METHOD : GET2021-01-26 18:19:02,559 [http-nio-8082-exec-2] INFO (LogAspect.java:39)- IP : 0:0:0:0:0:0:0:12021-01-26 18:19:02,559 [http-nio-8082-exec-2] INFO (HelloService.java:76)- <01>2021-01-26 18:19:02,560 [thread-1] INFO (SmsService.java:24)- <02>

2021-01-26 18:19:02,560 [http-nio-8082-exec-2] INFO (HelloService.java:78)- <04>2021-01-26 18:19:02,560 [thread-1] INFO (SmsService.java:26)- 正在发送短信...

2021-01-26 18:19:02,560 [http-nio-8082-exec-2] INFO (LogAspect.java:50)- RESPONSE : ⽤户注册成功

可以看到使⽤完成thread-3之后使⽤的⼜是thread-1了,线程池的参数可以根据⾃⼰项⽬的实际情况调整,不懂线程池的可以去看看我写的《》到此整合异步注解完成作者:彼岸舞时间:2021\\01\\26内容关于:SpringBoot

本⽂来源于⽹络,只做技术分享,⼀概不负任何责任

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务