日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

線程池遇到父子任務,有大坑,要注意!

來源: 責編: 時間:2024-07-17 07:45:11 658觀看
導讀你好呀,我是歪歪。最近在使用線程池的時候踩了一個坑,給你分享一下。在實際業務場景下,涉及到業務代碼和不同的微服務,導致問題有點難以定位,但是最終分析出原因之后,發現可以用一個很簡單的例子來演示。所以歪師傅這次先用

你好呀,我是歪歪。QP028資訊網——每日最新資訊28at.com

最近在使用線程池的時候踩了一個坑,給你分享一下。QP028資訊網——每日最新資訊28at.com

在實際業務場景下,涉及到業務代碼和不同的微服務,導致問題有點難以定位,但是最終分析出原因之后,發現可以用一個很簡單的例子來演示。QP028資訊網——每日最新資訊28at.com

所以歪師傅這次先用 Demo 說問題,再說場景,方便吸收。QP028資訊網——每日最新資訊28at.com

Demo

老規矩,還是先上個代碼:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

這個代碼的邏輯非常簡單,首先我們搞了一個線程池,然后起一個 for 循環往線程池里面仍了 5 個任務,這是核心邏輯。QP028資訊網——每日最新資訊28at.com

對于這幾個任務,我們的這個自定義線程池處理起來,不能說得心應手吧,至少也是手拿把掐。QP028資訊網——每日最新資訊28at.com

其他的 StopWatch 是為了統計運行時間用的。至于 CountDownLatch,你可以理解為在業務流程中,需要這五個任務都執行完成之后才能往下走,所以我搞了一個 CountDownLatch。QP028資訊網——每日最新資訊28at.com

這個代碼運行起來是沒有任何問題的,我們在日志中搜索“執行完成”,也能搜到 5 個,這個結果也能證明程序是正常結束的:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

同時,可以看到運行時間是 4s。QP028資訊網——每日最新資訊28at.com

示意圖大概是這樣的:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

然后歪師傅看著這個代碼,發現了一個可以優化的地方:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

這個地方從數據庫撈出來的數據,它們之間是沒有依賴關系的,也就是說它們之間也是可以并行執行的。QP028資訊網——每日最新資訊28at.com

所以歪師傅把代碼改成了這樣:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

在異步線程里面去處理這部分從數據庫中撈出來的數據,并行處理加快響應速度。QP028資訊網——每日最新資訊28at.com

對應到圖片,大概就是這個意思:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

把程序運行起來之后,日志變成了這樣:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

我們搜索“執行完成”,也能搜到 5 個對應輸出。QP028資訊網——每日最新資訊28at.com

而且我們就拿“任務2”來說:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

當前線程pool-1-thread-3,---【任務2】開始執行---當前線程pool-1-thread-3,---【任務2】執行完成---當前線程pool-1-thread-1,【任務2】開始處理數據=1當前線程pool-1-thread-2,【任務2】開始處理數據=2

從日志輸出來看,任務 2 需要處理的兩個數據,確實是在不同的異步線程中處理數據,也實現了我的需求。QP028資訊網——每日最新資訊28at.com

但是,程序運行直接就是到了 9.9ms:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

這個優化這么牛逼的嗎?QP028資訊網——每日最新資訊28at.com

從 4s 到了 9.9ms?QP028資訊網——每日最新資訊28at.com

稍加分析,你會發現這里面是有問題的。QP028資訊網——每日最新資訊28at.com

那么問題就來了,到底是啥問題呢?QP028資訊網——每日最新資訊28at.com

你也分析分析大概是啥問題,別老是想著直接找答案啊。QP028資訊網——每日最新資訊28at.com

問題就是由于轉異步了,所以 for 循環里面的任務中的 countDownLatch 很快就減到 0 了。QP028資訊網——每日最新資訊28at.com

于是 await 繼續執行,所以很快就輸出了程序運行時間。QP028資訊網——每日最新資訊28at.com

然而實際上子任務還在繼續執行,程序并沒有真正完成。QP028資訊網——每日最新資訊28at.com

9.9ms 只是任務提交到線程池的時間,每個任務的數據處理時間還沒算呢:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

從日志輸出上也可以看出,在輸出了 StopWatch 的日志后,各個任務還在處理數據。QP028資訊網——每日最新資訊28at.com

這樣時間就顯得不夠真實。QP028資訊網——每日最新資訊28at.com

那么我們應該怎么辦呢?QP028資訊網——每日最新資訊28at.com

很簡單嘛,需要子任務真正執行完成后,父任務的 countDownLatch 才能進行 countDown 的動作。QP028資訊網——每日最新資訊28at.com

具體實現上就是給子任務再加一個 countDownLatch 柵欄:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

我們希望的運行結果應該是這樣的:QP028資訊網——每日最新資訊28at.com

當前線程pool-1-thread-3,---【任務2】開始執行---當前線程pool-1-thread-1,【任務2】開始處理數據=1當前線程pool-1-thread-2,【任務2】開始處理數據=2當前線程pool-1-thread-3,---【任務2】執行完成---

即子任務全部完成之后,父任務才能算執行完成,這樣統計出來的時間才是準確的。QP028資訊網——每日最新資訊28at.com

思路清晰,非常完美,再次運行,觀察日志我們會發現:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

呃,怎么回事,日志怎么不輸出了?QP028資訊網——每日最新資訊28at.com

是的,就是不輸出了。QP028資訊網——每日最新資訊28at.com

不輸出了,就是踩到這個坑了。QP028資訊網——每日最新資訊28at.com

不論你重啟多少次,都是這樣:日志不輸出了,程序就像是卡著了一樣。QP028資訊網——每日最新資訊28at.com

坑在哪兒

上面這個 Demo 已經是我基于遇到的生產問題,極力簡化后的版本了。QP028資訊網——每日最新資訊28at.com

現在,這個坑也已經呈現在你眼前了。QP028資訊網——每日最新資訊28at.com

我們一起來分析一波。QP028資訊網——每日最新資訊28at.com

首先,我問你:真的在線上遇到這種程序“假死”的問題,你會怎么辦?QP028資訊網——每日最新資訊28at.com

早幾年,歪師傅的習慣是抱著代碼慢慢啃,試圖從代碼中找到端倪。QP028資訊網——每日最新資訊28at.com

這樣確實是可以,但是通常來說效率不高。QP028資訊網——每日最新資訊28at.com

現在我的習慣是直接把現場 dump 下來,分析現場。QP028資訊網——每日最新資訊28at.com

比如在這個場景下,我們直觀上的感受是“卡住了”,那就 dump 一把線程,管它有棗沒棗,打一桿子再說:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

通過 Dump 文件,可以發現線程池的線程都在 MainTest 的第 30 行上 parking ,處于等待狀態:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

那么第 30 行是啥玩意?QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

這行代碼在干啥?QP028資訊網——每日最新資訊28at.com

countDownLatchSub.await();QP028資訊網——每日最新資訊28at.com

是父任務在等待子任務執行結束,運行 finally 代碼,把 countDownLatchSub 的計數 countDown 到 0,才會繼續執行:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

所以現在的現象就是子任務的 countDownLatchSub 把父任務的攔住了。QP028資訊網——每日最新資訊28at.com

換句話說就是父任務被攔住是因為子任務的 finally 代碼中的 countDownLatchSub.countDown() 方法沒有被執行。QP028資訊網——每日最新資訊28at.com

好,那么最關鍵的問題就來了:為什么沒有執行?QP028資訊網——每日最新資訊28at.com

你先別往下看,閉上眼睛在你的小腦瓜子里面推演一下,琢磨一下:finally 為什么沒有執行?QP028資訊網——每日最新資訊28at.com

或者再換個更加接近真實的問題:子任務為什么沒有執行?QP028資訊網——每日最新資訊28at.com

這個點,非常簡單,可以說一點就破。QP028資訊網——每日最新資訊28at.com

琢磨明白了,這個坑的原理摸摸清楚了。QP028資訊網——每日最新資訊28at.com

...QP028資訊網——每日最新資訊28at.com

...QP028資訊網——每日最新資訊28at.com

...QP028資訊網——每日最新資訊28at.com

琢磨明白了嗎?你就刷刷往下看?QP028資訊網——每日最新資訊28at.com

沒明白我再給你一個信息:需要結合線程池的參數和運行原理來分析。QP028資訊網——每日最新資訊28at.com

什么?QP028資訊網——每日最新資訊28at.com

你說線程池的運行原理你不清楚?QP028資訊網——每日最新資訊28at.com

請你取關好嗎,你個假粉絲。QP028資訊網——每日最新資訊28at.com

...QP028資訊網——每日最新資訊28at.com

...QP028資訊網——每日最新資訊28at.com

...QP028資訊網——每日最新資訊28at.com

好,不管你“恍然大悟”了沒有,歪師傅給你講一下。QP028資訊網——每日最新資訊28at.com

讓你知道“一點就破”這四個是怎么回事兒。QP028資訊網——每日最新資訊28at.com

首先,我們把目光聚焦在線程池這里:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

這個線程池核心線程數是 3,但是我們要提交 5 個任務到線程池去。QP028資訊網——每日最新資訊28at.com

父任務哐哐哐,就把核心線程數占滿了。QP028資訊網——每日最新資訊28at.com

接下來子任務也要往這個線程池提交任務怎么辦?QP028資訊網——每日最新資訊28at.com

當然是進隊列等著了。QP028資訊網——每日最新資訊28at.com

一進隊列,就完犢子。QP028資訊網——每日最新資訊28at.com

到這里,我覺得你應該能想明白問題了。QP028資訊網——每日最新資訊28at.com

應該給到我一個恍然大悟的表情,并配上“哦哦哦~”這樣的內心 OS。QP028資訊網——每日最新資訊28at.com

你想想,父任務這個時候干啥?QP028資訊網——每日最新資訊28at.com

是不是等在 countDownLatchSub.await() 這里。QP028資訊網——每日最新資訊28at.com

而 countDownLatchSub.await() 什么時候能繼續執行?QP028資訊網——每日最新資訊28at.com

是不是要所有子任務都執行 finally 后?QP028資訊網——每日最新資訊28at.com

那么子任務現在在干啥?QP028資訊網——每日最新資訊28at.com

是不是都在線程池里面的隊列等著被執行呢?QP028資訊網——每日最新資訊28at.com

那線程池隊列里面的任務什么時候才執行?QP028資訊網——每日最新資訊28at.com

是不是等著有空閑線程的時候?QP028資訊網——每日最新資訊28at.com

那現在有沒有空閑線程?QP028資訊網——每日最新資訊28at.com

沒有,所有的線程都去執行父任務去了。QP028資訊網——每日最新資訊28at.com

那你想想,父任務這個時候干啥?QP028資訊網——每日最新資訊28at.com

是不是等在 countDownLatchSub.await() 這里。QP028資訊網——每日最新資訊28at.com

...QP028資訊網——每日最新資訊28at.com

父任務在等子任務執行。QP028資訊網——每日最新資訊28at.com

子任務在等線程池調度。QP028資訊網——每日最新資訊28at.com

線程池在等父任務釋放線程。QP028資訊網——每日最新資訊28at.com

閉環了,相互等待了,家人們。QP028資訊網——每日最新資訊28at.com

這,就是坑。QP028資訊網——每日最新資訊28at.com

現在把坑的原理摸清楚了,我在給你說一下真實的線上場景踩到這個坑是怎么樣的呢?QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

上游發起請求到微服務 A 的接口 1,該接口需要調用微服務 B 的接口 2。QP028資訊網——每日最新資訊28at.com

但是微服務 B 的接口 2,需要從微服務 A 接口 3 獲取數據。QP028資訊網——每日最新資訊28at.com

然而在微服務 A 內部,全局使用的是同一個自定義線程池。QP028資訊網——每日最新資訊28at.com

更巧的是接口 1 和接口 3 內部都使用了這個自定義線程池做異步并行處理,想著是加快響應速度。QP028資訊網——每日最新資訊28at.com

整個情況就變成了這樣:QP028資訊網——每日最新資訊28at.com

  1. 接口 1 收到請求之后,把請求轉到自定義線程池中,然后等接口 2 返回。
  2. 接口 2 調用接口 3,并等待返回。
  3. 接口 3 里面把請求轉到了自定義線程池中,被放入了隊列。
  4. 線程池的線程都被接口 1 給占住了,沒有資源去執行隊列里面的接口 3 任務。
  5. 相互等待,一直僵持。

我們的 Demo 還是能比較清晰的看到父子任務之間的關系。QP028資訊網——每日最新資訊28at.com

但是在這個微服務的場景下,在無形之間,就形成了不易察覺的父子任務關系。QP028資訊網——每日最新資訊28at.com

所以就踩到了這個坑。QP028資訊網——每日最新資訊28at.com

怎么避免

找到了坑的原因,解決方案就隨之而出了。QP028資訊網——每日最新資訊28at.com

父子任務不要共用一個線程池,給子任務也搞一個自定義線程池就可以了:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

運行起來看看日志:QP028資訊網——每日最新資訊28at.com

圖片圖片QP028資訊網——每日最新資訊28at.com

首先整體運行時間只需要 2s 了,達到了我想要的效果。QP028資訊網——每日最新資訊28at.com

另外,我們觀察一個具體的任務:QP028資訊網——每日最新資訊28at.com

當前線程pool-1-thread-3,---【任務2】開始執行---當前線程pool-2-thread-1,【任務2】開始處理數據=1當前線程pool-2-thread-4,【任務2】開始處理數據=2當前線程pool-1-thread-3,---【任務2】執行完成---

日志輸出符合我們前面分析的,所有子任務執行完成后,父任務才打印執行完成,且子任務在不同的線程中執行。QP028資訊網——每日最新資訊28at.com

而使用不同的線程池,換一個高大上的說法就叫做:線程池隔離。QP028資訊網——每日最新資訊28at.com

而且在一個項目中,公用一個線程池,也是一個埋坑的邏輯。QP028資訊網——每日最新資訊28at.com

至少給你覺得關鍵的邏輯,單獨分配一個線程池吧。QP028資訊網——每日最新資訊28at.com

避免出現線程池的線程都在執行非核心邏輯了,反而重要的任務在隊列里面排隊去了。QP028資訊網——每日最新資訊28at.com

這就有點不合理了。QP028資訊網——每日最新資訊28at.com

最后,一句話總結這個問題:QP028資訊網——每日最新資訊28at.com

如果線程池的任務之間存在父子關系,那么請不要使用同一個線程池。如果使用了同一個線程池,可能會因為子任務進了隊列,導致父任務一直等待,出現假死現象。QP028資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-101274-0.html線程池遇到父子任務,有大坑,要注意!

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: React 新 Hook:UseFormStatus 使用詳解

下一篇: B+樹層面查詢數據的全過程詳解

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
在线免费高清一区二区三区| 国产精品私拍pans大尺度在线 | 欧美自拍偷拍午夜视频| 久久国产天堂福利天堂| 欧美福利视频| 国产精品久久久久久久久久免费看| 国产一区二区激情| 亚洲精品国产视频| 香蕉成人伊视频在线观看| 美日韩免费视频| 欧美视频精品在线| 国产曰批免费观看久久久| 亚洲精品一区在线观看| 亚洲综合欧美日韩| 毛片一区二区三区| 国产精品美女久久久浪潮软件 | 国产欧美不卡| 亚洲欧洲在线观看| 新片速递亚洲合集欧美合集| 欧美a级一区| 国产精品每日更新在线播放网址| 在线观看成人av| 亚洲自啪免费| 欧美va亚洲va香蕉在线| 国产精品腿扒开做爽爽爽挤奶网站| 1769国内精品视频在线播放| 亚洲伊人第一页| 欧美成人自拍| 国产午夜精品全部视频播放| 99视频精品| 免费在线视频一区| 国产一区99| 亚洲香蕉网站| 欧美高清视频在线播放| 国产一区二区中文| 亚洲免费在线精品一区| 欧美激情在线播放| 尤物精品在线| 欧美尤物一区| 国产精品国产三级国产aⅴ9色| 亚洲黄色免费电影| 久久www成人_看片免费不卡| 欧美特黄一区| 亚洲精品国产精品乱码不99| 久久久久久综合网天天| 国产精品毛片a∨一区二区三区| 亚洲精品欧美一区二区三区| 久久人人精品| 国产亚洲高清视频| 亚洲欧美日韩区| 欧美视频不卡| 亚洲狼人综合| 麻豆av福利av久久av| 国产精品天天看| 亚洲私人影院在线观看| 欧美日韩精品在线| 亚洲精品美女在线观看播放| 欧美gay视频激情| 在线成人激情视频| 久久综合中文色婷婷| 韩国视频理论视频久久| 欧美亚洲免费电影| 国产精品入口尤物| 亚洲欧美激情一区| 国产精品青草久久| 亚洲一区二区三区中文字幕在线 | 欧美一区二区三区在线播放| 国产精品国码视频| 一区二区三区高清在线观看| 欧美交受高潮1| 亚洲国内自拍| 欧美高清你懂得| 亚洲丁香婷深爱综合| 麻豆国产精品va在线观看不卡| 在线观看日韩av| 久久这里只有| 亚洲成在人线av| 免费的成人av| 亚洲国产另类久久久精品极度| 久久婷婷av| 在线免费观看视频一区| 美女爽到呻吟久久久久| 亚洲国产99| 欧美精品99| 亚洲精品一区二区三区不| 欧美国产亚洲视频| 99re66热这里只有精品4| 欧美日韩国产综合视频在线观看中文| 亚洲乱码国产乱码精品精| 欧美日韩精品一本二本三本| 一区二区三区四区五区精品视频| 欧美视频二区36p| 亚洲欧美国内爽妇网| 国产亚洲精品v| 久久免费视频网站| 亚洲国产一区二区三区在线播| 欧美激情一区二区三区成人| 一区二区三区色| 国产欧美日韩三级| 久久免费国产| 99re这里只有精品6| 国产精品久久777777毛茸茸| 性欧美暴力猛交另类hd| 好吊一区二区三区| 欧美大片网址| 中日韩男男gay无套| 国产精品一区二区在线| 久久久久国产成人精品亚洲午夜| 在线观看一区| 欧美日韩国产页| 亚洲欧美日韩在线播放| 狠狠88综合久久久久综合网| 欧美国产成人在线| 亚洲永久免费观看| 黑丝一区二区三区| 欧美另类变人与禽xxxxx| 亚洲自拍偷拍一区| 黄色免费成人| 欧美日韩一区在线播放| 欧美一区视频| 在线成人中文字幕| 欧美日韩国产亚洲一区| 香港久久久电影| 91久久精品国产91久久| 国产精品一区二区久久久| 久久人人精品| 中日韩男男gay无套| 国产综合色一区二区三区 | 国产欧美日韩在线| 欧美不卡视频| 亚洲一区亚洲二区| 在线国产亚洲欧美| 国产精品av免费在线观看 | 欧美日韩亚洲一区二区三区在线观看 | 欧美天天综合网| 久久亚洲精品一区二区| 一区二区三区高清| 狠狠88综合久久久久综合网| 欧美日韩四区| 久久性天堂网| 亚洲一区免费| 亚洲国产精品久久久久婷婷老年| 国产精品理论片| 欧美成人免费观看| 欧美亚洲一级片| 99re6这里只有精品| 伊人婷婷久久| 欧美午夜不卡视频| 老司机一区二区| 午夜视频在线观看一区| 亚洲精品一区二区三区av| 国产一区二区三区久久久| 欧美日韩中文字幕在线视频| 久久中文在线| 欧美在线视频免费| 亚洲天堂av高清| 亚洲人被黑人高潮完整版| 国产一区二区黄色| 国产精品私拍pans大尺度在线| 欧美伦理在线观看| 久久综合狠狠| 欧美制服丝袜第一页| 亚洲午夜未删减在线观看| 亚洲精品国产欧美| 伊人婷婷久久| 国产综合欧美在线看| 国产精品制服诱惑| 欧美亚洲第一区| 欧美精品一区二区蜜臀亚洲| 久久美女性网| 欧美在线一二三四区| 亚洲欧美另类在线观看| 一区二区三区免费看| 亚洲精品美女| 亚洲人成久久| 亚洲国产欧美一区二区三区同亚洲| 国产一区二区在线观看免费播放 | 国产精品视频免费| 欧美日韩小视频| 欧美片网站免费| 欧美高清视频在线播放| 美女图片一区二区| 久久米奇亚洲| 久久久久综合网| 久久久久久久久岛国免费| 欧美一区二区三区免费大片| 亚洲一区二区在线观看视频| 一区二区三区日韩精品| 亚洲精品专区| 99这里只有精品| 一本久久综合| 一本一本大道香蕉久在线精品| 99国产精品久久久久久久| 亚洲卡通欧美制服中文| 亚洲毛片在线| 夜夜爽www精品| 亚洲视频在线观看| 亚洲在线视频观看| 午夜精品一区二区三区四区| 午夜亚洲福利| 欧美一二三区在线观看| 久久国产精品第一页| 久久久91精品国产| 久久性色av|