Java里面線程池的頂級(jí)接口是Executor,但是嚴(yán)格意義上講Executor并不是一個(gè)線程池,而只是一個(gè)執(zhí)行線程的工具。真正的線程池接口是ExecutorService。
下面這張圖完整描述了線程池的類體系結(jié)構(gòu)。

首先Executor的execute方法只是執(zhí)行一個(gè)Runnable的任務(wù),當(dāng)然了從某種角度上將最后的實(shí)現(xiàn)類也是在線程中啟動(dòng)此任務(wù)的。根據(jù)線程池的執(zhí)行策略最后這個(gè)任務(wù)可能在新的線程中執(zhí)行,或者線程池中的某個(gè)線程,甚至是調(diào)用者線程中執(zhí)行(相當(dāng)于直接運(yùn)行Runnable的run方法)。這點(diǎn)在后面會(huì)詳細(xì)說明。
ExecutorService在Executor的基礎(chǔ)上增加了一些方法,其中有兩個(gè)核心的方法:
- Future<?> submit(Runnable task)
- <T> Future<T> submit(Callable<T> task)
這兩個(gè)方法都是向線程池中提交任務(wù),它們的區(qū)別在于Runnable在執(zhí)行完畢后沒有結(jié)果,Callable執(zhí)行完畢后有一個(gè)結(jié)果。這在多個(gè)線程中傳遞狀態(tài)和結(jié)果是非常有用的。另外他們的相同點(diǎn)在于都返回一個(gè)Future對(duì)象。Future對(duì)象可以阻塞線程直到運(yùn)行完畢(獲取結(jié)果,如果有的話),也可以取消任務(wù)執(zhí)行,當(dāng)然也能夠檢測(cè)任務(wù)是否被取消或者是否執(zhí)行完畢。
在沒有Future之前我們檢測(cè)一個(gè)線程是否執(zhí)行完畢通常使用Thread.join()或者用一個(gè)死循環(huán)加狀態(tài)位來描述線程執(zhí)行完畢。現(xiàn)在有了更好的方法能夠阻塞線程,檢測(cè)任務(wù)執(zhí)行完畢甚至取消執(zhí)行中或者未開始執(zhí)行的任務(wù)。
ScheduledExecutorService描述的功能和Timer/TimerTask類似,解決那些需要任務(wù)重復(fù)執(zhí)行的問題。這包括延遲時(shí)間一次性執(zhí)行、延遲時(shí)間周期性執(zhí)行以及固定延遲時(shí)間周期性執(zhí)行等。當(dāng)然了繼承ExecutorService的ScheduledExecutorService擁有ExecutorService的全部特性。
ThreadPoolExecutor是ExecutorService的默認(rèn)實(shí)現(xiàn),其中的配置、策略也是比較復(fù)雜的,在后面的章節(jié)中會(huì)有詳細(xì)的分析。
ScheduledThreadPoolExecutor是繼承ThreadPoolExecutor的ScheduledExecutorService接口實(shí)現(xiàn),周期性任務(wù)調(diào)度的類實(shí)現(xiàn),在后面的章節(jié)中會(huì)有詳細(xì)的分析。
這里需要稍微提一下的是CompletionService接口,它是用于描述順序獲取執(zhí)行結(jié)果的一個(gè)線程池包裝器。它依賴一個(gè)具體的線程池調(diào)度,但是能夠根據(jù)任務(wù)的執(zhí)行先后順序得到執(zhí)行結(jié)果,這在某些情況下可能提高并發(fā)效率。
要配置一個(gè)線程池是比較復(fù)雜的,尤其是對(duì)于線程池的原理不是很清楚的情況下,很有可能配置的線程池不是較優(yōu)的,因此在Executors類里面提供了一些靜態(tài)工廠,生成一些常用的線程池。
- newSingleThreadExecutor:創(chuàng)建一個(gè)單線程的線程池。這個(gè)線程池只有一個(gè)線程在工作,也就是相當(dāng)于單線程串行執(zhí)行所有任務(wù)。如果這個(gè)唯一的線程因?yàn)楫惓=Y(jié)束,那么會(huì)有一個(gè)新的線程來替代它。此線程池保證所有任務(wù)的執(zhí)行順序按照任務(wù)的提交順序執(zhí)行。
- newFixedThreadPool:創(chuàng)建固定大小的線程池。每次提交一個(gè)任務(wù)就創(chuàng)建一個(gè)線程,直到線程達(dá)到線程池的最大大小。線程池的大小一旦達(dá)到最大值就會(huì)保持不變,如果某個(gè)線程因?yàn)閳?zhí)行異常而結(jié)束,那么線程池會(huì)補(bǔ)充一個(gè)新線程。
- newCachedThreadPool:創(chuàng)建一個(gè)可緩存的線程池。如果線程池的大小超過了處理任務(wù)所需要的線程,那么就會(huì)回收部分空閑(60秒不執(zhí)行任務(wù))的線程,當(dāng)任務(wù)數(shù)增加時(shí),此線程池又可以智能的添加新線程來處理任務(wù)。此線程池不會(huì)對(duì)線程池大小做限制,線程池大小完全依賴于操作系統(tǒng)(或者說JVM)能夠創(chuàng)建的最大線程大小。
- newScheduledThreadPool:創(chuàng)建一個(gè)大小無限的線程池。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。
- newSingleThreadScheduledExecutor:創(chuàng)建一個(gè)單線程的線程池。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。
在詳細(xì)講解ThreadPoolExecutor的時(shí)候會(huì)具體討論上述參數(shù)配置后的意義和原理。
線程池是一個(gè)復(fù)雜的任務(wù)調(diào)度工具,因此它涉及到任務(wù)、線程池等的生命周期問題,在下一節(jié)中來探討下這個(gè)問題。
©2009-2014 IMXYLZ
|求賢若渴