一、線程池的構造
一、線程池的構造
使用線程池離不開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線程池