Java線程池ThreadPoolExecutor-創(chuàng)新互聯(lián)

前言

多線程一直是Java進階的必修課。在Java中,我們很早就知道可以通過 Thread 類和 Runnable 接口來實現(xiàn)多線程。與之有著類似職責的數(shù)據(jù)庫連接,也可通過JDBC創(chuàng)建與使用。但我們深知無論是數(shù)據(jù)庫連接的創(chuàng)建與銷毀,還是線程的創(chuàng)建與銷毀,都是一件及其消耗性能的事情。為了減少這種情況的發(fā)生,前輩們就在思考,是不是可以復用已有的數(shù)據(jù)庫連接?減少創(chuàng)建,銷毀動作?這就是后來數(shù)據(jù)庫連接池的由來。同樣的,為了復用線程,也就有了線程池。我一直獨自暗喜,身為一位幸福的Java程序員,前有Java虛擬機管理內存,后有Doug Lea 大師提供并發(fā)庫,鎖機制。簡直幸福的不像話,不過幸福歸幸福,該掌握的還是需要掌握的,我們一起來看看今天的主角:ThreadPoolExecutor。

創(chuàng)新互聯(lián)是創(chuàng)新、創(chuàng)意、研發(fā)型一體的綜合型網(wǎng)站建設公司,自成立以來公司不斷探索創(chuàng)新,始終堅持為客戶提供滿意周到的服務,在本地打下了良好的口碑,在過去的十多年時間我們累計服務了上千家以及全國政企客戶,如成都廣告設計等企業(yè)單位,完善的項目管理流程,嚴格把控項目進度與質量監(jiān)控加上過硬的技術實力獲得客戶的一致表揚。
簡介

在面試過程中,也時常會遇到一些關于線程池的問題,例如:

  1. 線程池中核心參數(shù)有哪些?

  2. 有沒有自己實現(xiàn)過線程池?

  3. 如果讓你自己實現(xiàn)線程池,你會怎么做?

這些問題,其實考核的就是Java線程池的知識,更具體一點就是對ThreadPoolExector類熟不熟悉,下面代碼是ThreadPoolExector類的全參構造函數(shù)。下面我們就一一對參數(shù)進行了解。

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
?if (corePoolSize < 0 ||
?maximumPoolSize <= 0 ||
?maximumPoolSize < corePoolSize ||
?keepAliveTime < 0)
?throw new IllegalArgumentException();
?if (workQueue == null || threadFactory == null || handler == null)
?throw new NullPointerException();
?this.corePoolSize = corePoolSize;
?this.maximumPoolSize = maximumPoolSize;
?this.workQueue = workQueue;
?this.keepAliveTime = unit.toNanos(keepAliveTime);
?this.threadFactory = threadFactory;
?this.handler = handler;
?}

其中:

  1. corePoolSize:表示該線程池最小的工作線程數(shù)。默認情況下,當需要使用時創(chuàng)建線程,也可以調用 prestartAllCoreThreads() 方法進行預創(chuàng)建所有的核心線程。

  2. maximumPoolSize:表示該線程池大的線程數(shù)量,理論上將其設置為無限大,就會創(chuàng)建無限多的線程,當然,創(chuàng)建線程的數(shù)量最終由系統(tǒng)資源也就是操作系統(tǒng)決定。

  3. keepAliveTime:表示空閑線程的超時時間,(單位為納秒)。但在構造函數(shù)中,單位與unit 參數(shù)配合使用,最終轉換為納秒。

  4. unit:表示空閑線程超時的時間單位,可選值有:java.util.concurrent.TimeUnit中的值,SECONDS(秒),MINUTES(分),HOURS(小時),DAYS(天) 等。

  5. workQueue :表示工作隊列(其實是一個runnable隊列,在線程池中定義為Worker),其基類為:java.util.concurrent.BlockingQueue。

  6. threadFactory:線程工廠,通常用于創(chuàng)建線程,以及命令規(guī)則。默認為: Executors.defaultThreadFactory()。

  7. handler 表示處理策略,當workQueue隊列滿時,以及創(chuàng)建線程錯誤時的處理策略。其基類為 java.util.concurrent.RejectedExecutionHandler。默認為:AbortPolicy 策略。

不同組合

在 java.util.concurrent.Executors類為我們提供了多種組合,其底層還是調用ThreadPoolExecutor。下面列舉幾個常用的方法:

1.?newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {
? return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
...

特性:線程數(shù)量大小固定,且 corePoolSize 與 maximumPoolSize 數(shù)量相等。當線程數(shù)量設置太少時。task則會積壓在LinkedBlockingQueue隊列中。當 task 任務大于Integer.MAX_VALUE時 則會有OOM發(fā)生的風與之類是的還有newSingleThreadExecutor方法。

2. newCachedThreadPool

public static ExecutorService newCachedThreadPool() {
? return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

特性:corePoolSize數(shù)量為0,maximumPoolSize數(shù)量為Integer.MAX_VALUE,也就是說理論上是可以創(chuàng)建Integer.MAX_VALUE個線程的。keepAiveTime時間為 60秒。BlockingQueue使用的是SynchronousQueue,由于其沒用容量,意味這每一次put對應著一次take操作,其吞吐量比較高。正因為如此,當task到達一定程度時,可能會創(chuàng)建許多線程,從而導致OOM,甚至服務不可用。

上述方法其實是對ThreadPoolExecutor方法的封裝對不對,知道了ThreadPoolExecutor的每一個參數(shù),再來使用這個,就得心應手了對不對。

規(guī)范

Executors類這么方便,是不是可以直接使用Executors類來創(chuàng)建呢?當然可以,但并不建議這樣做。在《阿里Java手冊》中的并發(fā)處理小節(jié)中有提到:

【強制】線程池不允許使用 Executors 去創(chuàng)建,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式可以讓寫的同學更加明確線程池的運行規(guī)則,規(guī)避資源耗盡的風險。

說明:Executors 返回的線程池對象的弊端如下:
1) FixedThreadPool 和 SingleThreadPool :
允許的請求隊列長度為 Integer.MAX_VALUE,可能會堆積大量的請求,從而導致 OOM 。
2) CachedThreadPool 和 ScheduledThreadPool :允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE ,可能會創(chuàng)建大量的線程,從而導致 OOM 。

在實際應用中,我們應該遵守規(guī)范,避免掉一些沒必要的問題。該規(guī)約其最終目的是讓大家能夠更清楚了解線程池的每個參數(shù),從而達到能夠在實際應用場景中調為最優(yōu)組合使用,使其達到大性能。同樣的,我們也通過安裝阿里巴巴的規(guī)約插件進行自動掃描與提醒。在Idea中 File -> Setings -> Plugins -> Browse repositories中搜索『Alibaba Java Coding Guidelines』安裝即可!

小結

在這篇文章中,算是對ThreadPoolExector的一個初步了解。知道了其核心參數(shù),到底是怎么回事。但這還并不夠,且不足以學以致用,還有很多疑問,如:

  1. ThreadPoolExecutor的原理是怎樣的?

  2. 我們如何自定義一個線程池?

  3. ThreadPoolExecutor在Dubbo中的實踐

這些疑惑都需要一一去揭曉。由于篇幅原因,這些會作為好幾篇文章進行記錄。其目的是能夠學以致用,面試時也能得心應手。


相關閱讀:

《使用 Mybatis 真心不要偷懶!》

《再談Java 生產(chǎn)神器 BTrace》

《Java 生產(chǎn)神器 ?BTrace》

《重構不完全指南!》


如果想深入學習Java并發(fā)編程,下面這本書是值得閱讀的。當然了,如果你讀喜歡電子書,也可以回復公眾號消息『Java并發(fā)編程的藝術』進行免費獲??!

Java線程池ThreadPoolExecutor

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡助力業(yè)務部署。公司持有工信部辦法的idc、isp許可證, 機房獨有T級流量清洗系統(tǒng)配攻擊溯源,準確進行流量調度,確保服務器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務器買多久送多久。

當前文章:Java線程池ThreadPoolExecutor-創(chuàng)新互聯(lián)
轉載源于:http://muchs.cn/article22/eepcc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、關鍵詞優(yōu)化、網(wǎng)站改版網(wǎng)站排名、網(wǎng)站策劃、動態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設公司