国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JAVA 線程池的正確打開方式

894974231 / 440人閱讀

摘要:代碼如下是并發包中提供的,用來快速創建不同類型的線程池。線程池的正確創建方式其實,問題很好解決。總結最后,我們在使用線程池的時候,需要根據使用場景來自行選擇。擴展對于一些耗時的任務,盲目選擇線程池往往不是最佳方案。

JAVA 線程池的正確打開方式
摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog
當前環境

jdk == 1.8

Executors 使用的隱患

先來看一段代碼,我們要創建一個固定線程池,假設固定線程數是4。代碼如下:

Executors是JAVA并發包中提供的,用來快速創建不同類型的線程池。

是不是很簡單,創建線程池只需一行代碼。對于一些個人項目或臨時性的項目,這樣寫確實沒什么問題,而且開發速度很快。但在一些大型項目中,這種做法一般是禁止的。

WHY???

因為用Executors創建的線程池存在性能隱患,我們看一下源碼就知道,用Executors創建線程池時,使用的隊列是new LinkedBlockingQueue(),這是一個無邊界隊列,如果不斷的往里加任務時,最終會導致內存問題,也就是說在項目中由于使用了無邊界隊列,導致的內存占用的不可控性。下圖是不斷添加線程任務導致老年代被占滿的情況:

當然,除了內存問題,它還存在一些其他的問題,在下面對線程池參數的介紹中會具體說明。

線程池的正確創建方式

其實,問題很好解決。提供的簡便方式有局限性,那我們自己new一個ThreadPoolExecutor,無非多寫幾行代碼而已。

關于ThreadPoolExecutor的具體代碼如下:

參數說明:

corePoolSize:核心線程數;

maximumPoolSize:最大線程數,即線程池中允許存在的最大線程數;

keepAliveTime:線程存活時間,對于超過核心線程數的線程,當線程處理空閑狀態下,且維持時間達到keepAliveTime時,線程將被銷毀;

unit:keepAliveTime的時間單位

workQueue:工作隊列,用于存在待執行的線程任務;

threadFactory:創建線程的工廠,用于標記區分不同線程池所創建出來的線程;

handler:當到達線程數上限或工作隊列已滿時的拒絕處理邏輯;

具體代碼

自定義threadFactory。除了可以自定義創建的線程名稱,方便問題排查,在newThread(Runnable r)創建線程的方法中,還可以進行定制化設置,如為線程設置特定上下文等。

自定義RejectedExecutionHandler。記錄異常信息,選擇不同處理邏輯,有交由當前線程執行任務,有直接拋出異常,再或者等待后繼續添加任務等。

創建自定義線程池

線程池內在處理邏輯

我們通過一些例子,來觀察一下其內部的處理邏輯。基于上述具體代碼,我們已經創建了一個核心線程數4,最大線程數8,線程存活時間10s,工作隊列最大容量為10的一個線程池。

初始化線程池:未添加線程任務

這時,線程池中不會創建任何線程,存活線程為0,工作隊列為0.

未達核心線程數:添加4個線程任務

由于當前存活線程數 <= 核心線程數,所以會創建新的線程。即存活線程為4,工作隊列為0.

核心線程數已滿:添加第5個線程任務

若當前線程池中存在空閑線程,則交由該線程處理。即存活線程為4,工作隊列為0.

若當前所有線程處理運行狀態,加入工作隊列。即存活線程為4,工作隊列為1.(注意:此時工作隊列中的任務不會被執行,直到有線程空閑后,才能被處理

工作隊列未滿:假設添加的任務都是耗時操作(短時間不會結束),再添加9個耗時任務

即存活線程為4,工作隊列為10.

工作隊列已滿 & 未達最大線程數:再添加4個任務

當工作隊列已滿,且不存在空閑線程,此時會創建額外線程來處理當前任務。此時存活線程為8,工作隊列為10.

工作隊列已滿 & 且最大線程數已滿:再添加1個任務

觸發RejectedExecutionHandler,將當前任務交由自己設置的執行句柄進行處理。此時存活線程為8,工作隊列為10.

當任務執行完后,沒有新增的任務,臨時擴充的線程(大于核心線程數的)將在10s(keepAliveTime)后被銷毀。

總結

最后,我們在使用線程池的時候,需要根據使用場景來自行選擇。通過corePoolSize和maximumPoolSize的搭配,存活時間的選擇,以及改變隊列的實現方式,如:選擇延遲隊列,來實現定時任務的功能。并發包Executors中提供的一些方法確實好用,但我們仍需有保留地去使用,這樣在項目中就不會挖太多的坑。

擴展

對于一些耗時的IO任務,盲目選擇線程池往往不是最佳方案。通過異步+單線程輪詢,上層再配合上一個固定的線程池,效果可能更好。類似與Reactor模型中selector輪詢處理

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/76315.html

相關文章

  • 技術經理:求求你,別再亂改數據庫連接池的大小了!

    摘要:你僅僅需要一個大小為數據庫連接池,然后讓剩下的業務線程都在隊列里等待就可以了。你應該經常會看到一些用戶量不是很大的應用中,為應付大約十來個的并發,卻將數據庫連接池設置成,的情況。請不要過度配置您的數據庫連接池的大小。 文章翻譯整理自: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing歡迎關注個人微信公眾...

    darkbug 評論0 收藏0
  • 技術經理:求求你,別再亂改數據庫連接池的大小了!

    摘要:你僅僅需要一個大小為數據庫連接池,然后讓剩下的業務線程都在隊列里等待就可以了。你應該經常會看到一些用戶量不是很大的應用中,為應付大約十來個的并發,卻將數據庫連接池設置成,的情況。請不要過度配置您的數據庫連接池的大小。 文章翻譯整理自: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing歡迎關注個人微信公眾...

    蘇丹 評論0 收藏0
  • Java 線程池詳解

    摘要:最近項目中越來越多需要異步調用的地方,系統中雖有線程池管理,但還有可優化的空間,通過分享該文章,幫助大家了解線程池,同時學習使用線程池開啟線程需要注意的地方。沒錯,上述方法創建的線程池就是。線程池就是程序中的裝修公司,代勞各種臟活累活。 最近項目中越來越多需要異步調用的地方,系統中雖有線程池管理,但還有可優化的空間,通過分享該文章,幫助大家了解線程池,同時學習使用線程池開啟線程需要注意...

    fanux 評論0 收藏0
  • Java線程池簡單總結

    摘要:本文主要內容為簡單總結中線程池的相關信息。方法簇方法簇用于創建固定線程數的線程池。三種常見線程池的對比上文總結了工具類創建常見線程池的方法,現對三種線程池區別進行比較。 概述 線程可認為是操作系統可調度的最小的程序執行序列,一般作為進程的組成部分,同一進程中多個線程可共享該進程的資源(如內存等)。在單核處理器架構下,操作系統一般使用分時的方式實現多線程;在多核處理器架構下,多個線程能夠...

    CoorChice 評論0 收藏0

發表評論

0條評論

894974231

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<