<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot之SpringBoot整合異步線程調(diào)用注解

          共 5738字,需瀏覽 12分鐘

           ·

          2021-01-30 10:44

          點擊上方藍色字體,選擇“標星公眾號”

          優(yōu)質(zhì)文章,第一時間送達

          ? 作者?|? 彼岸舞

          來源 |? urlify.cn/a6ryIz

          76套java從入門到精通實戰(zhàn)課程分享

          理念:

            為了快速響應(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 秒


          感謝點贊支持下哈?

          瀏覽 60
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  福利毛片 | chaopeng97 | 激情乱伦91网站 | 黄色电影一级国产家庭乱伦 | 蜜桃av久久久亚洲精品 |