8.4 線程池

概念

定義:可以看做容納線程的容器,用于管理線程;

好處:1.減少在創(chuàng)建和銷毀線程上所花的時間以及系統(tǒng)資源的開銷;

? ? ? ? ? ?2.如不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量線程而導致消耗完系統(tǒng)內(nèi)存以及”過度切換”;

適用場景:適用于并發(fā)運行若干個運行時間不長且互不干擾的函數(shù)。

? ? ? ? ? ? ? ? ? 1.單個任務處理的時間比較短 ;(不是不能作長時間操作,而是不宜,并且還不能控制線程池中線程的開始、掛起、和中止)

? ? ? ? ? ? ? ? ? 2.將需處理的任務的數(shù)量大 ;


池化

概念:將資源交給池來管理的這一過程;

特點:1.通常管理昂貴的資源,如連接、線程等;(數(shù)據(jù)庫連接池、線程池)

? ? ? ? ? ?2.資源的創(chuàng)建和銷毀交給池,調(diào)用者不需要關(guān)心;

好處:1.資源重復利用,提高響應速度;

? ? ? ? ? ?2.資源可管理,可監(jiān)控;


線程池類結(jié)構(gòu)

類結(jié)構(gòu)

ForkJoinPool:并行計算框架;

ThreadPoolExecutor:Java線程池的實現(xiàn),Executors提供的幾種線程池主要使用該類;

ScheduledThreadPoolExecutor:繼承自ThreadPoolExecutor,添加了調(diào)度功能;


ThreadPoolExecutor邏輯結(jié)構(gòu)和工作方式

int corePoolSize :線程池基本大小(核心線程池大?。?;

int maximumPoolSize:線程池最大大?。?/p>

long keepAliveTime :保持活動時間;

BlockingQueue workQueue:工作隊列;

ThreadFactory threadFactory:線程工廠;

RejectedExecutionHandler handler :駁回回調(diào);

ThreadPoolExecutor

java兩種基礎(chǔ)線程池:ScheduledThreadPoolExecutor和ThreadPoolExecutor,都實現(xiàn)了ExecutorService接口;

ExecutorService:接口本身和“線程池”并沒有直接關(guān)系,它的定義更接近“執(zhí)行器”,而“使用線程管理的方式進行實現(xiàn)”只是其中的一種實現(xiàn)方式;

線程池執(zhí)行submit()方法或者execute()方法時,幾種處理情況如下:

1.當前線程池中運行的線程數(shù)量 未達到 corePoolSize的大小,創(chuàng)建新線程執(zhí)行任務;(無視已創(chuàng)建線程是否空閑)

2.當前線程池中運行的線程數(shù)量 已達到 corePoolSize的大小,

? ? ? ? 1)將任務加入等待隊列,等待某一線程空閑,根據(jù)等待規(guī)則從隊列中取出新任務執(zhí)行;

? ? ? ? 2)無法加入等待隊列,創(chuàng)建“非核心線程”直接運行該任務;(這種情況下當前線程池中運行線程數(shù)量一定大于corePoolSize)

注:如果1,2均不符合,即該任務無法被“核心線程”直接執(zhí)行、無法加入等待隊列、無法被“非核心線程”執(zhí)行

? ? ? ?此時,若且未設(shè)置RejectedExecutionHandler(駁回)則拋出RejectedExecutionException異常,即線程池拒絕接受這個任務?;

回收邏輯:當線程池中的線程 超過 設(shè)置的corePoolSize的大小,(即核心線程和非核心線程都有)

? ? ? ? ? ? ? ? ? 此時,當某個線程處理完任務后,如果等待keepAliveTime時間后仍然沒有新的任務分配給它,那么這個線程將會被回收;

? ? ? ? ? ? ? ? (回收線程對所謂的“核心線程”和“非核心線程”是一視同仁的,直到線程池中線程的數(shù)量等于corePoolSize,回收過程才會停止)?

Hook methods

hook methods

ThreadPoolExecutor狀態(tài)

RUNNING:初始狀態(tài),接受新任務并且處理已經(jīng)在隊列中的任務;

SHUTDOWN:不接受新任務,但處理隊列中的任務;

STOP:不接受新任務,不處理排隊的任務,并中斷正在進行的任務;

TIDYING:所有任務已終止,workerCount為零,線程轉(zhuǎn)換到狀態(tài)TIDYING,這時回調(diào)terminate()方法;

TERMINATED:終態(tài),terminated()執(zhí)行完成;

狀態(tài)轉(zhuǎn)換

RejectedExecutionHandler

當隊列滿 且 線程池大小 >= maximumPoolSize時會觸發(fā)駁回,因為這時線程池已經(jīng)不能響應新提交的任務,駁回時就會回調(diào)這個接口rejectedExecution方法,JDK默認提供了4種駁回策略,默認策略是AbortPolicy:

駁回策略

使用

Executor:使我們無需顯示的去管理線程的生命周期,是JDK 5之后啟動任務的首選方式;

ExecutorService:繼承自Executor,它的目的是為我們管理Thread對象,從而簡化并發(fā)編程;

1.創(chuàng)建固定大小的線程池(FixedThreadPool)

特點:創(chuàng)建一個可重用固定線程集合的線程池,以共享的無界隊列方式來運行這些線程;

固定容量大小的線程池

2.緩存線程池(CachedThreadPool)

特點:1.創(chuàng)建一個緩存區(qū),將初始化的線程緩存起來(60秒未用從緩存中移除),可用就重用,不可用就新建;

? ? ? ? ? ?2. 線程池的大小會根據(jù)執(zhí)行的任務數(shù)動態(tài)分配;

緩存線程池

3.單線程線程池(SingleThreadExecutor)

特點:創(chuàng)建單個線程的線程池,如果當前線程在執(zhí)行任務時突然中斷,則會創(chuàng)建一個新的線程替代它繼續(xù)執(zhí)行任務;

? ?注:和直接創(chuàng)建線程不同,也和newFixedThreadPool(1)不同;

單線程線程池

4.定時線程池(ScheduledThreadPool)

特點:創(chuàng)建一個可安排在給定延遲后運行命令或者定期地執(zhí)行的線程池;

定時線程池

線程池中使用Callable

Callable和Future一個產(chǎn)生結(jié)果,一個拿到結(jié)果。

FutureTask實現(xiàn)了兩個接口,Runnable和Future,所以它既可以作為Runnable被線程執(zhí)行,又可以作為Future得到Callable的返回值;

線程池中獲取返回值
獲取多個返回值

注:excute與submit方法區(qū)別

? ? ? ?excute:1.是在Executor接口中定義的;

? ? ? ? ? ? ? ? ? ? ? 2.只支持傳入Runnable;

? ? ? ?submit:1.是在ExecutorService定義的,本質(zhì)是調(diào)用父類的excute;

? ? ? ? ? ? ? ? ? ? ? 2.支持傳入Runnable和Callable(即支持Future,可用于獲取返回值);

結(jié)論:1.如果提交的任務不需要一個結(jié)果的話直接用execute()會提升很多性能;

? ? ? ? ? ?2.1:需要結(jié)果使用submit(Callable task);????????????????//維護了一個new FutureTask(callable)

? ? ? ? ? ?2.2:需要特定結(jié)果submit(Runnable task, T result);? //維護了一個new FutureTask(runnable, value)

? ? ? ? ? ?2.3:需要空結(jié)果submit(Runnable task);? ? ? ? ? ? ? ? ?//維護了一個new FutureTask(runnable, null)

????????(2.2特定結(jié)果與2.3空結(jié)果都是自己設(shè)的返回值,與Callable接口無關(guān))


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容