国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - 編程技術 - 什么?用@Async會內存溢出?看看你的線程池配置了沒!

什么?用@Async會內存溢出?看看你的線程池配置了沒!

2021-09-18 01:23程序猿DD翟永超 編程技術

如果只是如前文那樣直接簡單的創建來使用,可能還是會碰到一些問題。存在有什么問題呢?先來思考下,下面的這個接口,通過異步任務加速執行的實現,是否存在問題或風險呢?

什么?用@Async會內存溢出?看看你的線程池配置了沒!

上一篇我們介紹了如何使用@Async注解來創建異步任務,我可以用這種方法來實現一些并發操作,以加速任務的執行效率。但是,如果只是如前文那樣直接簡單的創建來使用,可能還是會碰到一些問題。存在有什么問題呢?先來思考下,下面的這個接口,通過異步任務加速執行的實現,是否存在問題或風險呢?

  1. @RestController
  2. publicclassHelloController{
  3.  
  4. @Autowired
  5. privateAsyncTasksasyncTasks;
  6.  
  7. @GetMapping("/hello")
  8. publicStringhello(){
  9. //將可以并行的處理邏輯,拆分成三個異步任務同時執行
  10. CompletableFuturetask1=asyncTasks.doTaskOne();
  11. CompletableFuturetask2=asyncTasks.doTaskTwo();
  12. CompletableFuturetask3=asyncTasks.doTaskThree();
  13.  
  14. CompletableFuture.allOf(task1,task2,task3).join();
  15. return"HelloWorld";
  16. }
  17. }

雖然,從單次接口調用來說,是沒有問題的。但當接口被客戶端頻繁調用的時候,異步任務的數量就會大量增長:3 x n(n為請求數量),如果任務處理不夠快,就很可能會出現內存溢出的情況。那么為什么會內存溢出呢?根本原因是由于Spring Boot默認用于異步任務的線程池是這樣配置的:

什么?用@Async會內存溢出?看看你的線程池配置了沒!

圖中我標出的兩個重要參數是需要關注的:

  • queueCapacity:緩沖隊列的容量,默認為INT的最大值(2的31次方-1)。
  • maxSize:允許的最大線程數,默認為INT的最大值(2的31次方-1)。

所以,默認情況下,一般任務隊列就可能把內存給堆滿了。所以,我們真正使用的時候,還需要對異步任務的執行線程池做一些基礎配置,以防止出現內存溢出導致服務不可用的問題。

配置默認線程池

默認線程池的配置很簡單,只需要在配置文件中完成即可,主要有以下這些參數:

  1. spring.task.execution.pool.core-size=2
  2. spring.task.execution.pool.max-size=5
  3. spring.task.execution.pool.queue-capacity=10
  4. spring.task.execution.pool.keep-alive=60s
  5. spring.task.execution.pool.allow-core-thread-timeout=true
  6. spring.task.execution.shutdown.await-termination=false
  7. spring.task.execution.shutdown.await-termination-period=
  8. spring.task.execution.thread-name-prefix=task-

具體配置含義如下:

  • spring.task.execution.pool.core-size:線程池創建時的初始化線程數,默認為8
  • spring.task.execution.pool.max-size:線程池的最大線程數,默認為int最大值
  • spring.task.execution.pool.queue-capacity:用來緩沖執行任務的隊列,默認為int最大值
  • spring.task.execution.pool.keep-alive:線程終止前允許保持空閑的時間
  • spring.task.execution.pool.allow-core-thread-timeout:是否允許核心線程超時
  • spring.task.execution.shutdown.await-termination:是否等待剩余任務完成后才關閉應用
  • spring.task.execution.shutdown.await-termination-period:等待剩余任務完成的最大時間
  • spring.task.execution.thread-name-prefix:線程名的前綴,設置好了之后可以方便我們在日志中查看處理任務所在的線程池

動手試一試

我們直接基于之前chapter7-5的結果來進行如下操作。

首先,在沒有進行線程池配置之前,可以先執行一下單元測試:

  1. @Test
  2. publicvoidtest1()throwsException{
  3. longstart=System.currentTimeMillis();
  4.  
  5. CompletableFuturetask1=asyncTasks.doTaskOne();
  6. CompletableFuturetask2=asyncTasks.doTaskTwo();
  7. CompletableFuturetask3=asyncTasks.doTaskThree();
  8.  
  9. CompletableFuture.allOf(task1,task2,task3).join();
  10.  
  11. longend=System.currentTimeMillis();
  12.  
  13. log.info("任務全部完成,總耗時:"+(end-start)+"毫秒");
  14. }

由于默認線程池的核心線程數是8,所以3個任務會同時開始執行,日志輸出是這樣的:

  1. 2021-09-1500:30:14.819INFO77614---[task-2]com.didispace.chapter76.AsyncTasks:開始做任務二
  2. 2021-09-1500:30:14.819INFO77614---[task-3]com.didispace.chapter76.AsyncTasks:開始做任務三
  3. 2021-09-1500:30:14.819INFO77614---[task-1]com.didispace.chapter76.AsyncTasks:開始做任務一
  4. 2021-09-1500:30:15.491INFO77614---[task-2]com.didispace.chapter76.AsyncTasks:完成任務二,耗時:672毫秒
  5. 2021-09-1500:30:19.496INFO77614---[task-3]com.didispace.chapter76.AsyncTasks:完成任務三,耗時:4677毫秒
  6. 2021-09-1500:30:20.443INFO77614---[task-1]com.didispace.chapter76.AsyncTasks:完成任務一,耗時:5624毫秒
  7. 2021-09-1500:30:20.443INFO77614---[main]c.d.chapter76.Chapter76ApplicationTests:任務全部完成,總耗時:5653毫秒

接著,可以嘗試在配置文件中增加如下的線程池配置

  1. spring.task.execution.pool.core-size=2
  2. spring.task.execution.pool.max-size=5
  3. spring.task.execution.pool.queue-capacity=10
  4. spring.task.execution.pool.keep-alive=60s
  5. spring.task.execution.pool.allow-core-thread-timeout=true
  6. spring.task.execution.thread-name-prefix=task-

日志輸出的順序會變成如下的順序:

  1. 2021-09-1500:31:50.013INFO77985---[task-1]com.didispace.chapter76.AsyncTasks:開始做任務一
  2. 2021-09-1500:31:50.013INFO77985---[task-2]com.didispace.chapter76.AsyncTasks:開始做任務二
  3. 2021-09-1500:31:52.452INFO77985---[task-1]com.didispace.chapter76.AsyncTasks:完成任務一,耗時:2439毫秒
  4. 2021-09-1500:31:52.452INFO77985---[task-1]com.didispace.chapter76.AsyncTasks:開始做任務三
  5. 2021-09-1500:31:55.880INFO77985---[task-2]com.didispace.chapter76.AsyncTasks:完成任務二,耗時:5867毫秒
  6. 2021-09-1500:32:00.346INFO77985---[task-1]com.didispace.chapter76.AsyncTasks:完成任務三,耗時:7894毫秒
  7. 2021-09-1500:32:00.347INFO77985---[main]c.d.chapter76.Chapter76ApplicationTests:任務全部完成,總耗時:10363毫秒
  • 任務一和任務二會馬上占用核心線程,任務三進入隊列等待
  • 任務一完成,釋放出一個核心線程,任務三從隊列中移出,并占用核心線程開始處理

注意:這里可能有的小伙伴會問,最大線程不是5么,為什么任務三是進緩沖隊列,不是創建新線程來處理嗎?這里要理解緩沖隊列與最大線程間的關系:只有在緩沖隊列滿了之后才會申請超過核心線程數的線程來進行處理。所以,這里只有緩沖隊列中10個任務滿了,再來第11個任務的時候,才會在線程池中創建第三個線程來處理。這個這里就不具體寫列子了,讀者可以自己調整下參數,或者調整下單元測試來驗證這個邏輯。

原文鏈接:https://mp.weixin.qq.com/s/1LgXMWS26vJvfakrA24rNg

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 玖玖视频 | 国产精品99一区二区三区 | 可以在线观看的av网站 | 成人在线小视频 | 凹凸日日摸日日碰夜夜爽孕妇 | 欧美日韩久久 | 精品国产乱码久久久久久丨区2区 | 久久蜜桃av一区二区天堂 | 成年人黄色免费视频 | 久久成人一区 | 欧美狠狠操 | 久久99一区二区 | 99re热精品视频 | 在线国产视频 | 国产性猛交xxxx免费看久久 | 伊人成人222 | 国产视频一区二区视频 | 韩日精品一区 | 国产区在线 | 亚洲字幕| 国产精品高潮呻吟久久 | 九九综合 | 亚洲性网| 久久久久久久久久久久福利 | 欧美福利网址 | 一区久久 | 亚洲91精品| 国产 欧美 日韩 一区 | 91亚洲一区 | 日韩国产欧美一区 | 久久午夜精品 | 日本久久精品一区 | 国产精品久久久久久久久久东京 | 在线一级片 | 国产日韩欧美精品 | 中文字幕视频在线观看 | 精品一区二区三区免费毛片爱 | 国产香蕉视频在线播放 | 亚洲免费中文字幕 | 九九re热| 毛片特级|