Java- 技術專題 - 多線程之線程池

一、線程池的構造

一、線程池的構造
使用線程池離不開ThreadPoolExecutor類,該類實現了ExecutorService接口,其構造方法如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler);1
參數說明如下:
corePoolSize:核心池大小

maximumPoolSize:線程池大小(maximumPoolSize >= corePoolSize)

keepAliveTime:沒有任務時線程的存活時間,默認情況下只有線程數目大於corePoolSize時,此參數才起作用,若線程數目等於corePoolSize,則這些線程會一直存活。但若調用allowCoreThreadTimeOut(boolean)方法,則線程數目不大於corePoolSize時,此參數也起作用,直到線程數目爲0

unit:keepAliveTime的時間單位,有以下七種取值:

TimeUnit.DAYS;//天

TimeUnit.HOURS;//小時

TimeUnit.MINUTES;//分鐘

TimeUnit.SECONDS;//秒

TimeUnit.MILLISECONDS;//毫秒

TimeUnit.MICROSECONDS;//微秒

TimeUnit.NANOSECONDS;//納秒

workQueue:指定構成緩衝區的阻塞隊列,即指定了線程池的排隊策略,常用的有以下三種:

ArrayBlockingQueue:基於數組的先進先出隊列,此隊列創建時必須指定大小

LinkedBlockingQueue:基於鏈表的先進先出隊列,如果創建時沒有指定此隊列大小,則默認爲Integer.MAX_VALUE

synchronousQueue:這個隊列不會保存提交的任務,而是將直接新建一個線程來執行新來的任務

threadFactory(可選):線程工廠,用來創建線程,可自定義

handler(可選):拒絕策略,有以下四種策略可選:

ThreadPoolExecutor.AbortPolicy:丟棄任務並拋出RejectedExecutionException異常。

ThreadPoolExecutor.DiscardPolicy:丟棄任務,不拋出異常。

ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,然後重新嘗試執行任務

ThreadPoolExecutor.CallerRunsPolicy:由調用線程處理該任務

二、線程池的運行過程

如果當前線程池中的線程數目小於corePoolSize,則每來一個任務,就會創建一個線程去執行這個任務如果當前線程池中的線程數目>=corePoolSize,則每來一個任務,會嘗試將其添加到任務緩存隊列當中,若添加成功,則該任務會等待空閒線程將其取出去執行;若添加失敗(一般來說是任務緩存隊列已滿),則會嘗試創建新的線程去執行這個任務

如果當前線程池中的線程數目達到maximumPoolSize,則會採取任務拒絕策略進行處理

如果線程池中的線程數量大於corePoolSize時,如果某線程空閒時間超過keepAliveTime,線程將被終止,直至線程池中的線程數目不大於corePoolSize;

如果允許爲核心池中的線程設置存活時間(調用allowCoreThreadTimeOut(boolean)方法),那麼核心池中的線程空閒時間超過keepAliveTime,線程也會被終止

三、線程的初始化

默認情況下,線程池構造完成後是沒有線程的,需要等任務提交時纔會創建線程,如果需要在線程池構造完成時就創建線程,可以調用以下兩個方法:

prestartCoreThread():初始化一個核心線程;

prestartAllCoreThreads():初始化所有核心線程

四、線程池的關閉

shutdown():不會立即關閉線程池,而是不再接受新的任務,等當前所有任務處理完之後關閉線程池

shutdownNow():立即關閉線程池,打斷正在執行的任務,清空緩衝隊列,返回尚未執行的任務

五、任務提交

任務提交有兩種方法,execute()和submit()

void execute(Runnable task),無返回值

Future<T>submit(Runnable task, T result) /Future<T>submit(Callable<T> task),有返回值

六、可選線程池模型(Executors類的靜態工廠方法)

newCachedThreadPool():**ThreadPoolExecutor(0,Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>())**

newFixedThreadPool(int nThreads):**ThreadPoolExecutor(nThreads,nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>())**

newSingleThreadExecutor:**ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>())**

newScheduledThreadPool(int nThreads):**ScheduledThreadPoolExecutor(nThreads,Integer.MAX_VALUE,0L,TimeUnit.NANOSECONDS,new DelayedWorkQueue())**

newSingleScheduledThreadPool():**newScheduledThreadPool(1)**

調用實例:**ExecutorService pool = Executors.newCachedThreadPool();**

構造線程池時優先選用線程池模型,如果這些模型不能滿足要求,再自定義ThreadPoolExecutor線程池

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章