一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

「JDK并發(fā)包基礎(chǔ)」線程池詳解

 Bladexu的文庫 2019-03-10

我們每次執(zhí)行一個多線程任務時用new Thread,這樣頻繁創(chuàng)建對象會導致系統(tǒng)性能差,線程也缺乏統(tǒng)一管理,可能會無限制新建線程,相互之間競爭導致系統(tǒng)資源耗盡,并且缺乏定時任務,中斷等功能。

線程池可以有效的提高系統(tǒng)資源的使用率,同時避免過多資源競爭,重用存在的線程,減少對象創(chuàng)建。

「JDK并發(fā)包基礎(chǔ)」線程池詳解

為了更好的控制多線程,JDK提供了一套線程框架Executor來幫助程序員有效的進行線程控制。Java.util.concurrent 包是專為 Java并發(fā)編程而設(shè)計的包,其中有一個比較重要的線程工廠類:Executors。

Java通過Executors創(chuàng)建不同功能的線程池,若Executors無法滿足需求,我們也可以創(chuàng)建自定義的線程池。本文分為以下部分講解:

  1. newFixedThreadPool()方法
  2. newSingleThreadExecutor()方法
  3. newCachedThreadPool()方法
  4. newScheduledThreadPool()方法
  5. 自定義線程池

在講述之前,因為上面5條在方法體內(nèi)部其實是創(chuàng)建了ThreadPoolExecutor這個類的對象,所以我們先來看看ThreadPoolExecutor中線程執(zhí)行任務的示意圖,它的執(zhí)行任務分兩種情況:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

1).Execute()方法會創(chuàng)建一個線程然后執(zhí)行一個任務。

2).這個線程在執(zhí)行完1之后,會反復從BlockingQueue隊列(可以看我的上一篇文章【JDK并發(fā)包基礎(chǔ)】并發(fā)容器詳解)中獲取任務來執(zhí)行。如果圖中所示三個線程同時間在執(zhí)行任務,還有任務進來則會放入BlockingQueue隊列中暫緩起來等待線程空閑去執(zhí)行。

再者,這3個線程正在使用,隊列也滿了的話(有界隊列的情況),還有任務進來,則會實行拒絕策略。(take()和poll()都是取頭元素節(jié)點,區(qū)別在于前者會刪除元素,后者不會)

1.newFixedThreadPool()方法

創(chuàng)建一個固定數(shù)量的線程池,里面的線程數(shù)始終不變,當有一個線程提交時,若線程池中有空閑的線程,則立即執(zhí)行。若沒有,則會暫緩在一個阻塞隊列LinkedBlockingQueue中等待有空閑的線程去執(zhí)行。newFixedThreadPool()方法的源碼如下:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

現(xiàn)在我們思考一下:假如有Thread1、Thread2、Thread3、Thread4四條線程分別統(tǒng)計C、D、E、F四個盤的大小,所有線程都統(tǒng)計完畢交給Thread5線程去做匯總,應當如何實現(xiàn)?

第一種方式是用join()來做,不推薦:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

推薦使用線程池的方式:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

運行結(jié)果如下,統(tǒng)計前四個盤大小可以沒有順序,但合計始終在最后:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

2. newSingleThreadExecutor()方法

創(chuàng)建只有一個線程的線程池,若線程池中有空閑的線程,則立即執(zhí)行。若沒有,則會暫緩在一個阻塞隊列LinkedBlockingQueue中等待有空閑的線程去執(zhí)行,它保證所有任務按照提交順序執(zhí)行。我們來看看newSingleThreadExecutor方法的源碼:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

應用場景:這個線程池會在僅有的一個線程發(fā)生異常時,重新啟動一個線程來替代原來的線程執(zhí)行下去。

3.newCachedThreadPool()方法

創(chuàng)建一個可根據(jù)實際情況調(diào)整線程個數(shù)的線程池,不限制線程數(shù)量。若有任務,則創(chuàng)建線程。若無任務,則不創(chuàng)建線程,并且每一個空閑的線程會在60秒后自動回收。我們來看看源碼:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

源碼中的SynchronousQueue這個沒有容量的隊列一創(chuàng)建,內(nèi)部就使用take()方法阻塞著,當有一個線程來了直接就執(zhí)行。

4.newScheduledThreadPool()方法

創(chuàng)建一個大小無限的線程池,此線程池支持定時以及周期性執(zhí)行任務的需求。它的源碼如下:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

源碼中的DelayedWorkQueue是帶有延遲時間的一個隊列,其中元素只有當指定時間到了,才能夠從隊列中獲取元素,可以做定時的功能。

創(chuàng)建一個任務,等3秒初始化后每隔1秒打印一句話:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

這個類似于Java的Timer定時器,但項目中用Quartz,跟Spring整合的話,最好用@Scheduled注解。ref:Spring Schedule 任務調(diào)度實現(xiàn)

5.自定義線程池

在上述Executors工廠類創(chuàng)建線程池時,它的創(chuàng)建線程方法內(nèi)部實現(xiàn)均用了ThreadPoolExecutor這個類,ThreadPoolExecutor可以實現(xiàn)自定義線程池,它的構(gòu)造方法如下:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

這個構(gòu)造方法對于BlockingQueue隊列是什么類型比較關(guān)鍵,它關(guān)乎這個自定義線程池的功能。

1.使用有界隊列ArrayBlockingQueue時,實際線程數(shù)小于corePoolSize時,則創(chuàng)建線程。若大于corePoolSize時,則任務會加入BlockingQueue隊列中,若隊列已滿,則在實際線程總數(shù)不大于maximumPoolSize時,創(chuàng)建新線程。若還大于maximumPoolSize,則執(zhí)行拒絕策略,或者自定義的其他方式。

2.使用無界隊列LinkedBlockingQueue時,緩沖隊列,當實際線程超過corePoolSize核心線程數(shù)后放置等待的線程,最后等系統(tǒng)空閑了在這個隊列里取,maximumPoolSize參數(shù)在這里就沒有作用了。因為它是無界隊列,所以除非系統(tǒng)資源耗盡,否則不會出現(xiàn)任務入隊失敗的情況。比如創(chuàng)建任務的速度和處理速度差異很大,無界隊列會保持快速增長,直到系統(tǒng)內(nèi)存耗盡。

有界隊列和無界隊列實例如下:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

用LinkedBlockingQueue無界隊列執(zhí)行后結(jié)果是每過一段時間5個任務一執(zhí)行:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

對于拒絕策略,即當任務數(shù)量超過了系統(tǒng)實際承載能力時該如何處理呢?JDK提供了幾種實現(xiàn)策略:

AbortPolicy:直接拋出異常來阻止系統(tǒng)正常工作。

CallerRunsPolicy:只要線程池未關(guān)閉,會把丟棄的任務先執(zhí)行。

DiscardOledestPolicy:丟棄最老的一個請求,嘗試再次提交當前任務

DiscardPolicy:丟棄無法處理的任務,不給于任何處理。

這四種策略個人覺得都不太好,我們可以實現(xiàn)一個自定義策略,在這里實現(xiàn)RejectedExecutionHandler接口就好了:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

「JDK并發(fā)包基礎(chǔ)」線程池詳解

運行結(jié)果如下:

「JDK并發(fā)包基礎(chǔ)」線程池詳解

到這里已經(jīng)介紹完了Java并發(fā)包下的線程池,博主是個普通的程序猿,水平有限,文章難免有錯誤,歡迎犧牲自己寶貴時間的讀者,就本文內(nèi)容直抒己見。

系列:

【JDK并發(fā)包基礎(chǔ)】線程池詳解

【JDK并發(fā)包基礎(chǔ)】并發(fā)容器詳解

【JDK并發(fā)包基礎(chǔ)】工具類詳解

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    精品精品国产自在久久高清| 美国欧洲日本韩国二本道| 国产精品久久香蕉国产线| 国产欧美日韩不卡在线视频| 老司机精品线观看86| 国产又黄又猛又粗又爽的片| 99国产成人免费一区二区| 成人区人妻精品一区二区三区| 麻豆蜜桃星空传媒在线观看| 国产精品香蕉免费手机视频| 国产精品日本女优在线观看| 国产又粗又长又爽又猛的视频| 日本特黄特色大片免费观看| 内射精品欧美一区二区三区久久久| 亚洲国产精品国自产拍社区| 欧美熟妇喷浆一区二区| 精品人妻一区二区四区| 白丝美女被插入视频在线观看| 丁香六月婷婷基地伊人| 久久亚洲精品中文字幕| 日韩视频在线观看成人| 日本99精品在线观看| 大香伊蕉欧美一区二区三区| 日系韩系还是欧美久久| 欧美黑人巨大一区二区三区| 不卡一区二区在线视频| 91欧美激情在线视频| 99久久人妻中文字幕| 亚洲最新的黄色录像在线| 日韩人妻免费视频一专区| 国产精品美女午夜福利| 欧美一级黄片免费视频| 国产亚洲成av人在线观看 | 国产精品一区二区日韩新区| 少妇毛片一区二区三区| 日本黄色高清视频久久| 日本在线视频播放91| 成人免费在线视频大香蕉| 一区二区三区国产日韩| 欧美野外在线刺激在线观看| 精品人妻一区二区三区四在线|