SpringBoot之SpringBoot整合異步線程調(diào)用注解
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質(zhì)文章,第一時間送達
? 作者?|? 彼岸舞
來源 |? urlify.cn/a6ryIz
理念:
為了快速響應(yīng)瀏覽器,開啟多線程執(zhí)行任務(wù)
?但是有一個缺點,會增加CPU資源的消耗,所以大的項目推薦使用MQ消息隊列
編寫代碼:
@GetMapping("/addDB")
????public?String?addDB()?{
????????//?模擬數(shù)據(jù)交互
????????log.info("<01>");
????????sms();
????????log.info("<04>");
????????return?"用戶注冊成功";
????}
????/**
?????*?模擬發(fā)送短信
?????*
?????*?@return
?????*/
????public?String?sms()?{
????????log.info("<02>");
????????try?{
????????????log.info("正在發(fā)送短信...");
????????????Thread.sleep(3000);
????????}?catch?(InterruptedException?e)?{
????????????e.printStackTrace();
????????}
????????return?"短信發(fā)送完成";
????}
這個接口最少需要4秒才能返回,如果發(fā)送短信時間更長,返回時間增加,這樣用戶的體驗就非常不好
啟動項目測試

?
?他是單線程去執(zhí)行的,看過Tomcat的應(yīng)該也知道,tomcat會為每一次請求從他的線程池中單獨拿一個線程去執(zhí)行,所以它是單線程?的
所以這里就可以使用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?{
????/**
?????*?模擬發(fā)送短信
?????*
?????*?@return
?????*/
????@Async
????public?String?sms()?{
????????log.info("<02>");
????????try?{
????????????log.info("正在發(fā)送短信...");
????????????Thread.sleep(3000);
????????}?catch?(InterruptedException?e)?{
????????????e.printStackTrace();
????????}
????????return?"短信發(fā)送完成";
????}
????
}
通過Autowirld的方式注入使用

?
?再次測試

?
?
?可以看到執(zhí)行成功了,并且也是不同的線程,但是他這樣都是每次都是new一個新的線程,這顯然是不合理的,因為使用線程就應(yīng)該考慮采用線程池
異步注解整合線程池:
創(chuàng)建config包,并在下面創(chuàng)建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;
????/**
?????*?線程池維護線程的最大數(shù)量
?????*?(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();
????????//?設(shè)置核心線程數(shù)
????????executor.setCorePoolSize(corePoolSize);
????????//?設(shè)置最大線程數(shù)
????????executor.setMaxPoolSize(maxPoolSize);
????????//?設(shè)置隊列容量
????????executor.setQueueCapacity(queueCapacity);
????????//?設(shè)置允許的空閑時間(秒)
????????//executor.setKeepAliveSeconds(keepAlive);
????????//?設(shè)置默認線程名稱
????????executor.setThreadNamePrefix("thread-");
????????//?設(shè)置拒絕策略rejection-policy:當(dāng)pool已經(jīng)達到max size的時候,如何處理新任務(wù)
????????// CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是有調(diào)用者所在的線程來執(zhí)行
????????executor.setRejectedExecutionHandler(new?ThreadPoolExecutor.CallerRunsPolicy());
????????//?等待所有任務(wù)結(jié)束后再關(guān)閉線程池
????????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)-?正在發(fā)送短信...
<執(zhí)行定時任務(wù)>:18:18:56
<執(zhí)行定時任務(wù)>:18:19:01
2021-01-26?18:19:01,340?[http-nio-8082-exec-3]?INFO?(LogAspect.java:37)-?URL?:?http://localhost:8082/addDB
2021-01-26?18:19:01,341?[http-nio-8082-exec-3]?INFO?(LogAspect.java:38)-?HTTP_METHOD?:?GET
2021-01-26?18:19:01,341?[http-nio-8082-exec-3]?INFO?(LogAspect.java:39)-?IP?:?0:0:0:0:0:0:0:1
2021-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)-?正在發(fā)送短信...
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/addDB
2021-01-26?18:19:01,922?[http-nio-8082-exec-4]?INFO?(LogAspect.java:38)-?HTTP_METHOD?:?GET
2021-01-26?18:19:01,923?[http-nio-8082-exec-4]?INFO?(LogAspect.java:39)-?IP?:?0:0:0:0:0:0:0:1
2021-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)-?正在發(fā)送短信...
2021-01-26?18:19:02,559?[http-nio-8082-exec-2]?INFO?(LogAspect.java:37)-?URL?:?http://localhost:8082/addDB
2021-01-26?18:19:02,559?[http-nio-8082-exec-2]?INFO?(LogAspect.java:38)-?HTTP_METHOD?:?GET
2021-01-26?18:19:02,559?[http-nio-8082-exec-2]?INFO?(LogAspect.java:39)-?IP?:?0:0:0:0:0:0:0:1
2021-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)-?正在發(fā)送短信...
2021-01-26?18:19:02,560?[http-nio-8082-exec-2]?INFO?(LogAspect.java:50)-?RESPONSE?:?用戶注冊成功
可以看到使用完成thread-3之后使用的又是thread-1了,線程池的參數(shù)可以根據(jù)自己項目的實際情況調(diào)整,不懂線程池的可以去看看我寫的《線程池理念分析及其手寫》
到此整合異步注解完成
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長按上方微信二維碼?2 秒
感謝點贊支持下哈?
評論
圖片
表情
