JAVA執行緒池學習筆記
執行緒池的作用
普通的執行緒用法是,每次任務都new一個新執行緒去執行,任務完成後,執行緒也就等著被銷燬。
使用執行緒池可以管理執行緒的建立、排程和複用,執行完任務的執行緒不會被銷燬,可以繼續執行其他任務。
執行緒池實現的相關重要成員
threadFactory:建立執行緒的工廠類,執行緒池中所有的執行緒都是由它來生成。
worker:執行任務的工作執行緒,執行任務時,如果需要新增worker,會把該任務當做worker的firstTask,由worker持有的執行緒來執行任務。We implement a simple non-reentrant mutual exclusion lock rather than use reentrantLock because we do not want worker tasks to be able to reacquire the lock when they invoke pool control methods likesetCorePoolSize.
corePoolSize:核心池的大小即worker保活的最小數量。如果執行緒池內worker的數量小於corePoolSIze,每次接受新任務,都會建立新的worker來執行任務,如果worker的數量大於等於corePoolSize,新增的任務會被新增到阻塞佇列workerQueue(BlockingQueue)。
maximumPoolSize:執行緒池中worker的最大容量。
workerQueue:任務阻塞佇列。當worker數量達到了corePoolSize,新進的任務,會被存放在workerQueue,之後交由worker執行。一般有三種實現:ArrayBlockQueue、LinkedBlockingQueue和SYnchronousQueue。不同的實現,決定了執行緒池排隊策略的不同。
keepAliveTime:worker執行完任務後的存活時間,也就是說worker的空閒時間超過keepAliveTime,就會被處理。預設情況下,keepAliveTime起作用分兩種情況:如果worker數量小於corePoolSIze,keepAliveTime不會起作用,空閒的worker可以一直等待新的任務。如果worker數量超過corePoolSize,worker的空閒時間達到keepAliveTime,就會被銷燬。
allowCoreThreadTimeOut:如果它的值為true,不管worker數量是否到達corePoolSIze,worker的空閒時間達到keepAliveTime,都會被銷燬。
rejectedExcutionHandler:當worker數量達到maximumPoolSize或者執行緒池處於shutDown的狀態,執行緒池會呼叫這個handler來處理新進的任務。handler的取值就是拒絕處理任務時的策略,有四種:
CallerRunsPolicy:A handler for rejected tasks that runs the rejected task directly in the calling thread of the method,unless the executor has been shut down, in which case the task is discarded.
AbortPolicy:A handler for rejected tasks that throws a RejectedExecutionException。
DiscardPolicy:A handler for rejected tasks that silently discards the rejected task。
DiscardOldestPolicy:A handler for rejected tasks that discards the oldest unhandled request and then retries, unless the executor is shut down, in which case the task is discarded。
執行緒池的執行機制
執行緒池初始化建立後,通過execute()方法,向執行緒池中新增任務task。
1 worker數量小於corePoolSIze,會建立新的worker來執行任務。
2 worker數量大於等於corePoolSIze,此時又分兩種情況:task成功新增到workerQueue,等待有空閒執行緒來提取、執行任務。workerQueue新增失敗(一般來說是任務快取佇列已滿),則會嘗試建立新的執行緒去執行這個任務。
3 當worker的數量超過maximumPoolSize,新進的任務將呼叫rejectedExecutionHandler來處理。同時,當執行緒池處於shutdown的狀態時,新進的任務也將呼叫rejectedExecutionHandler來處理。
4 worker執行完任務後會從workerQueue提取並執行新的任務。而當worker處於空閒狀態,會根據worker數量是否大於corePoolSize以及allowCoreThreadTimeOut是否為true,判斷keepAliveTime是否生效。
4.1 worker數量超過corePoolSize。keepAliveTime有效,則當worker的空閒時間到達keepAliveTime,將被銷燬,直到worker數量不超過corePoolSIze。
4.2 worker數量不超過corePoolSize同時allowCoreThreadTimeOut為false,keepAliveTime無效,空閒worker會一直等來執行新的任務
4.3 worker數量不超過corePoolSize同時allowCoreThreadTimeOut為true,keepAliveTime有效,當worker的空閒時間到達keepAliveTime,將被銷燬,不管worker的數量是否超過corePoolSIze。
執行緒池的狀態
RUNNING:當建立執行緒池後,初始時,執行緒池處於RUNNING狀態
SHUTDOWN:如果呼叫了shutdown()方法,則執行緒池處於SHUTDOWN狀態,此時執行緒池不能夠接受新的任務,它會等待所有任務執行完畢;此時還能通過getTask()獲取workerQueue中待執行的任務
STOP:如果呼叫了shutdownNow()方法,則執行緒池處於STOP狀態,此時執行緒池不能接受新的任務,並且會去嘗試終止正在執行的任務;在STOP狀態下,就不能從getTask()獲取workQueue中待執行的任務
TERMINATED:當執行緒池處於SHUTDOWN或STOP狀態,並且所有工作執行緒已經銷燬,任務快取佇列已經清空或執行結束後,執行緒池被設定為TERMINATED狀態。