第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么使用的線程數(shù)高于要求?

為什么使用的線程數(shù)高于要求?

慕姐4208626 2022-12-28 16:30:15
我有一個 SpringBoot 應用程序,我最多允許 45 個并發(fā)請求。 現(xiàn)在,旅程中的1 個請求使用.parallel并行調用16 個外部服務threadPool A。因此,請牢記平均情況和最壞情況,我一直遵循以下配置:ThreadPoolTaskExecutor A = new ThreadPoolTaskExecutor();A.setCorePoolSize(400);A.setMaxPoolSize(1000);A.setQueueCapacity(10);A.setThreadNamePrefix("async-executor");A.initialize();我的期望是最多使用 45*16 = 720 個線程。但是在運行負載測試時,我觀察到線程不斷打開(在線程轉儲中檢查),幾分鐘后它開始給出 RejectedExecutionException。RejectedExecutionExceptionTask ServiceX rejected from org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor$1@4221a19e[Running, poolsize = 1000, active threads = 2, queued tasks = 10, completed tasks = 625216]線程轉儲中顯示的大多數(shù)線程"executor-A-57" #579 prio=5 os_prio=0 tid=0x000000000193f800 nid=0x2e95 waiting on condition [0x00007fa9e820c000]   java.lang.Thread.State: TIMED_WAITING (parking)    at sun.misc.Unsafe.park(Native Method)    - parking to wait for  <0x0000000582dadf90> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)    at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)    at java.lang.Thread.run(Thread.java:748)   Locked ownable synchronizers:    - None我想知道我在這里缺少什么?為什么我會被拒絕?
查看完整描述

2 回答

?
富國滬深

TA貢獻1790條經(jīng)驗 獲得超9個贊

這是一個有趣的。


您列出的代碼失敗的原因是因為將元素從工作隊列傳輸?shù)焦ぷ骶€程所花費的時間比主線程將項目放入隊列所花費的時間慢。


流程是這樣的:


if(there are active threads and is there availability on the queue){

    submit to the work queue for the worker threads to pick up // 1

} else {

   if(max pool size is not met){

      create a new thread with this task being its first task // 2

   } else { 

      reject // 3

   }

您看到的是代碼命中// 3.


首次提交任務時,線程數(shù)將小于最大池大小。第一輪提交的任務將到達// 2。


第一次迭代后,活動線程的數(shù)量將是最大池大小,代碼將嘗試提交到// 1.


假設主線程非常非??斓貙?3 個項目放入隊列,因此 ThreadPool 中的 4 個線程無法足夠快地取出一個。如果發(fā)生這種情況,我們將傳遞第一個 if 語句(因為隊列中沒有可用性)并轉到 else。由于已經(jīng)滿足最大池大小,因此除了reject.

這可以通過檢查ThreadPoolExecutor Javadocs進一步解釋。

如果請求無法排隊,則會創(chuàng)建一個新線程,除非這會超過 maximumPoolSize,在這種情況下,任務將被拒絕。

然后

直接切換通常需要無限的 maximumPoolSizes 以避免拒絕新提交的任務。當命令的平均到達速度繼續(xù)快于它們的處理速度時,這反過來又承認了無限線程增長的可能性。

要解決您的問題,您有兩個合理的選擇:

  1. 使用同步隊列。提供給 SynchronousQueue 的線程將無限期地等待,直到另一個線程獲取該項目(如果它知道另一個線程正在等待接收它)。您定義的固定隊列大小將導致主線程在放置不成功時返回(不阻塞)(即,另一個線程不會立即將其取消)。要使用 Spring 使用 SynchronousQueue,請將隊列容量設置為零。setQueueCapacity(0). 也來自 Javadocs

    工作隊列的一個很好的默認選擇是 SynchronousQueue,它將任務交給線程而不用其他方式持有它們。

  2. 將隊列大小設置為大于或等于您希望提交的并發(fā)任務數(shù)。隊列的大小一般不會達到那個大小,但它會在未來保護你。


查看完整回答
反對 回復 2022-12-28
?
PIPIONE

TA貢獻1829條經(jīng)驗 獲得超9個贊

我建議通過添加 1 個輸出任務執(zhí)行程序的記錄器行來對此進行測試,然后對不同的 16 次調用和 45 次請求進行計數(shù)??赡軙l(fā)生很多事情。

  1. 也許 ThreadPoolTaskExecutor 不是一個 bean,而 spring 會選擇另一個在您的應用程序中配置的 bean。

  2. 也許應用程序的其他部分也在使用異步調用

  3. 永遠循環(huán)的代碼中可能存在一些錯誤

ETC...

但是,如果您沒有單元測試,一個好的開始是簡單地記錄正在發(fā)生的事情并分析您的日志。


查看完整回答
反對 回復 2022-12-28
  • 2 回答
  • 0 關注
  • 134 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號