AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

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

不同業務使用同一個線程池發生死鎖

來源: 責編: 時間:2024-09-10 09:50:21 102觀看
導讀在我們進行代碼開發時,我也見過很多全局注冊一個自定義線程池(也有可能不是自定義的,直接使用更不推薦Executors 創建的線程池),也許是業務量不高、也許是其他原因,反正全局可這一個線程池使勁造。一、看個代碼業務邏輯代碼

在我們進行代碼開發時,我也見過很多全局注冊一個自定義線程池(也有可能不是自定義的,直接使用更不推薦Executors 創建的線程池),也許是業務量不高、也許是其他原因,反正全局可這一個線程池使勁造。ACs28資訊網——每日最新資訊28at.com

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

一、看個代碼

業務邏輯代碼:ACs28資訊網——每日最新資訊28at.com

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

自定義線程池 BizThreadPool 代碼如下:ACs28資訊網——每日最新資訊28at.com

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

通過上方的代碼示例,如果你還沒有看出問題,那你可以停留幾秒思考一下。ACs28資訊網——每日最新資訊28at.com

自定義線程池創建,使用的這個隊列,嗯......,大家工作中一定不要這么用,此處只是為了做演示使用。ACs28資訊網——每日最新資訊28at.com

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

如果你已經看出來了問題所在,也希望你能繼續看下去,驗證一下咱們是不是想的相同。ACs28資訊網——每日最新資訊28at.com

二、有啥問題

經過短暫幾秒鐘的思考之后,決定還是運行一下 Demo 看看現象。ACs28資訊網——每日最新資訊28at.com

封裝一個 controller 直接啟動 Springboot 程序,Java 啟動。ACs28資訊網——每日最新資訊28at.com

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

啟動成功之后調用 GET http://localhost:8080/test/test,輸出結果如下。ACs28資訊網——每日最新資訊28at.com

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

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

按照我們的預期,日志中應該也要輸出子任務才對啊,怎么創建的子任務沒有輸出呢,看現象應該是沒有執行。ACs28資訊網——每日最新資訊28at.com

那我們先執行一下 jstack 命令看一下線程相關的信息,輸出信息中其中一段如下所示。ACs28資訊網——每日最新資訊28at.com

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

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

通過上面的堆棧信息可以看出,主線程在將父任務執行完成之后,開啟了一個CountDownLatch并等待3個子任務執行完成。ACs28資訊網——每日最新資訊28at.com

問題就在這,一直等待,一直等不到結果,所以就是我們剛開始看到的結果,只有父任務執行了,子任務并沒有執行。ACs28資訊網——每日最新資訊28at.com

一次調用沒有響應,多次調用之后,達到服務器資源瓶頸時系統就該發生崩潰了。ACs28資訊網——每日最新資訊28at.com

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

那么子任務為何沒有執行到呢?ACs28資訊網——每日最新資訊28at.com

三、小試牛刀

首先我們從頭開始捋一下,先看下線程池的配置。ACs28資訊網——每日最新資訊28at.com

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

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

我們在創建自定義線程池時,核心線程與最大線程都設置的1,那我們直接修改最大線程數量,讓線程池有線程可以執行子任務不就行了嗎?ACs28資訊網——每日最新資訊28at.com

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

對于生產中,核心線程與最大線程一般也不會設置為1,但是哪怕你設置為10、100、1000,極端情況下也會出現本文后面將要講述的問題。ACs28資訊網——每日最新資訊28at.com

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

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

說干就干,創建自定義線程池的代碼變為了如下形式。ACs28資訊網——每日最新資訊28at.com

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

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

非常自信的你重啟程序,然后調用接口,最終傻眼了,怎么沒變化?ACs28資訊網——每日最新資訊28at.com

如果你修改完最大線程數就去重啟程序的話,說明線程池的工作原理你已經忘了!ACs28資訊網——每日最新資訊28at.com

好吧原諒你了,這次不準再忘了,下面跟我一起來看看這究竟是什么原因。ACs28資訊網——每日最新資訊28at.com

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

四、線程池工作流程

這里放一下線程池的工作流程。ACs28資訊網——每日最新資訊28at.com

面試官:線程池核心線程設置為0時任務執行流程怎么樣的ACs28資訊網——每日最新資訊28at.com

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

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

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

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

知道了線程池的工作流程之后,在上述代碼中,哪怕增加了最大線程池的數量,最終子任務也并不會執行到,我們可以打印一下當前線程池的狀態進行輔助觀察。(上述代碼的printThreadPoolStatus()方法會進行線程池當前狀態的打印)ACs28資訊網——每日最新資訊28at.com

調用一下GET http://localhost:8080/test/info方法查看線程池當前的狀態。ACs28資訊網——每日最新資訊28at.com

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

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

可以看到隊列中存在3個任務在排隊,等待線程池分配線程執行任務。這也就是修改了最大線程池數量未生效的原因,因為還有一個無界隊列。ACs28資訊網——每日最新資訊28at.com

當然如果任務一直增加,隊列中任務數量越來越多,達到服務器的瓶頸,就會發生OOM了。(阿里開發規范中不推薦使用無界隊列的原因)ACs28資訊網——每日最新資訊28at.com

五、修改核心線程數量

那我們直接修改核心線程數量吧,核心線程超過任務數量?ACs28資訊網——每日最新資訊28at.com

回答:不行。ACs28資訊網——每日最新資訊28at.com

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

對于我們上面的例子來說,增加核心線程數量,擁有可以執行子任務的線程,確實可以解決當下場景。ACs28資訊網——每日最新資訊28at.com

但是當并發量上來之后,或者說線程池的線程都被父線程所占用時,依舊會發現子任務無法獲得線程執行。ACs28資訊網——每日最新資訊28at.com

此處我們修改核心線程為10執行看一下輸出結果。ACs28資訊網——每日最新資訊28at.com

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

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

通過修改核心線程數量,解決了子任務在隊列中堆積的問題。ACs28資訊網——每日最新資訊28at.com

所以通過上述代碼,大家應該知道死鎖是怎么發生的了吧,這里我總結一下。ACs28資訊網——每日最新資訊28at.com

六、小結

當核心線程為1,最大線程為1,使用無界隊列。父任務在線程中等待子任務完成的通知,子任務在線程池的任務隊列中等待線程池調度線程資源。ACs28資訊網——每日最新資訊28at.com

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

當核心線程為1,最大線程為n,使用無界隊列。最大線程設置n與設置1沒有區別,除非使用的隊列不同,只要是使用的無界隊列,當資源耗盡之時,就是服務崩潰的時候。此時后面新的父任務到來時,也只會在任務隊列中繼續堆積。ACs28資訊網——每日最新資訊28at.com

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

當核心線程為n,最大線程為n,使用無界隊列。核心線程設置為n,意味著父線程大概率是可以執行的,創建的子任務在任務隊列中排隊執行。ACs28資訊網——每日最新資訊28at.com

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

當并發量上來,或者核心線程都被父任務所占據之后,線程池調用就變成了如下場景,所有的任務都被堆積在任務隊列當中:ACs28資訊網——每日最新資訊28at.com

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

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

核心線程全是父任務,后面創建的任務也都在任務隊列堆積,最終達到服務器瓶頸系統OOM。ACs28資訊網——每日最新資訊28at.com

七、最終解決方案

通過上述代碼示例,死鎖的根本原因在于,父任務會創建多個子任務,并等待子任務執行結束,而父子任務都是使用的同一個線程池,當線程池中執行線程都是父任務時,所有的子任務又都在任務隊列中等待執行,所以這樣就會發生死鎖。ACs28資訊網——每日最新資訊28at.com

核心線程永遠不會釋放,從而造成任務隊列不斷堆積,直到OOM。ACs28資訊網——每日最新資訊28at.com

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

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

所以解決方案就是,隔離線程池。ACs28資訊網——每日最新資訊28at.com

不同的業務使用不同的線程池,使用一個新的線程池處理子任務,這樣就可以避免死鎖的發生了。ACs28資訊網——每日最新資訊28at.com

修改之后的代碼如下。ACs28資訊網——每日最新資訊28at.com

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

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

通過查看日志輸出可以發現,線程池隔離之后,哪怕核心線程設置為1,也是可以正常執行業務邏輯的,任務隊列中也沒有堆積任務。ACs28資訊網——每日最新資訊28at.com

八、總結

通過上面的 Demo 復現以及解決方案,在工作中優化建議如下:ACs28資訊網——每日最新資訊28at.com

  • 禁止使用Executors創建自定義線程池。使用ThreadPoolExecutor創建線程池時,注意每個參數的含義,規避資源耗盡的風險。
  • 線程池使用有界隊列,避免使用無界隊列。
  • 對于父子任務的場景,可以使用線程池或者 MQ。使用有界隊列之后,制定合理的拒絕策略,拒絕策略可以考慮 MQ 做重試。
  • 不同業務使用不同的線程池,禁止父子任務使用相同的線程池。

本文鏈接:http://www.tebozhan.com/showinfo-26-112764-0.html不同業務使用同一個線程池發生死鎖

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

上一篇: Python必知必會:15個令人相見恨晚的Python字符串格式化技巧!

下一篇: 玩轉文件權限:Python 的七個權限操作實戰

標簽:
  • 熱門焦點
  • 盧偉冰長文解析K60至尊版 對Redmi有著里程碑式的意義

    在今天的Redmi后性能時代戰略發布會結束之后,Redmi總經理盧偉冰又帶來了一篇長文,詳解了為什么 Redmi 要開啟后性能時代?為什么選擇和 MediaTek、Pixelworks 深度合作?以及后性
  • 《英雄聯盟》夏季賽總決賽今日開打!JDG對陣LNG首發名單來了 Knight:準備三連冠

    8月5日消息,今日17:00,《英雄聯盟》2023LPL夏季賽總決賽將正式開打,由JDG對陣LNG。對兩支隊伍來說,這場比賽不僅要爭奪夏季賽冠軍,更要決定誰才是LPL賽區一
  • JavaScript 混淆及反混淆代碼工具

    介紹在我們開始學習反混淆之前,我們首先要了解一下代碼混淆。如果不了解代碼是如何混淆的,我們可能無法成功對代碼進行反混淆,尤其是使用自定義混淆器對其進行混淆時。什么是混
  • 得物效率前端微應用推進過程與思考

    一、背景效率工程隨著業務的發展,組織規模的擴大,越來越多的企業開始意識到協作效率對于企業團隊的重要性,甚至是決定其在某個行業競爭中突圍的關鍵,是企業長久生存的根本。得物
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 講故事上個月我寫過一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,當時用的是 GDIView + WinDbg 把問題搞定,前者用來定位泄露資源,后者用來定位泄露代碼,后面有朋友反
  • JVM優化:實戰OutOfMemoryError異常

    一、Java堆溢出堆內存中主要存放對象、數組等,只要不斷地創建這些對象,并且保證 GC Roots 到對象之間有可達路徑來避免垃 圾收集回收機制清除這些對象,當這些對象所占空間超過
  • 拼多多APP上線本地生活入口,群雄逐鹿萬億市場

    Tech星球(微信ID:tech618)文 | 陳橋輝 Tech星球獨家獲悉,拼多多在其APP內上線了“本地生活”入口,位置較深,位于首頁的“充值中心”內,目前主要售賣美食相關的
  • 阿里瓴羊One推出背后,零售企業迎數字化新解

    作者:劉曠近年來隨著數字經濟的高速發展,各式各樣的SaaS應用服務更是層出不窮,但本質上SaaS大多局限于單一業務流層面,對用戶核心關切的增長問題等則沒有提供更好的解法。在Saa
  • 利用職權私自解除被封帳號 Meta開除20多名員工

    11月18日消息,據外媒援引知情人士表示,過去一年時間內,Facebook母公司Meta解雇或處罰了20多名員工以及合同工,指控這些人通過內部系統以不當方式重置用戶帳號,其
Top