線程池
線程池解決了兩個不同的問題:
- 減少線程創建的開銷,能提高執行大量異步任務的效率
- 提供了一種限制和管理資源及線程的方法,並且還維護了一些基本的統計信息(如已完成的任務數)
線程池的使用對new Thread()
的優勢:
- 複用存在的線程,減少對象創建、消亡的開銷,性能佳。
- 可有效控制最大併發線程數,提高系統資源的使用率,同時避免過多資源競爭,避免堵塞。
- 提供定時執行、定期執行、單線程、併發數控制等功能。
ThreadPoolExecutor
常用默認實現:
Executors#newCachedThreadPool
:無邊界線程池,帶有自動線程回收Executors#newFixedThreadPool
:固定大小的線程池Executors#newSingleThreadExecutor
:單個後臺線程,大多數場景用於預初始化配置
有需要執行的任務進入線程池時
- 當前線程數小於核心線程數時,創建線程。
- 當前線程數大於等於核心線程數,且工作隊列未滿時,將任務放入工作隊列。
- 當前線程數大於等於核心線程數,且工作隊列已滿
- 若線程數小於最大線程數,創建線程
- 若線程數等於最大線程數,拋出異常,拒絕任務(具體處理方式取決於
handler
的策略)
主要參數
-
corePoolSize
核心線程數。空閒時仍會保留在池中的線程數,除非設置了allowCoreThreadTimeOut
參數 -
maximumPoolSize
最大線程數。允許在池中的最大線程數 -
keepAliveTime
存活時間。當前線程數大於核心線程數時,空餘線程的最長存活時間 -
unit
單位。keepAliveTime
參數的時間單位 -
workQueue
工作隊列,接口類爲阻塞隊列。任務執行前存儲的隊列,只有通過submit
方法提交的任務纔會進入隊列 -
threadFactory
線程工廠。創建線程。默認使用Executors.defaultThreadFactory()
,所有的線程都屬於同一個ThreadGroup
,都有相同的優先級,且均不是守護線程。
(可用new NamedThreadFactory("test")
來對線程池中的線程添加前綴標識) -
handler
任務丟棄策略。若線程池已經關閉、或線程池已滿,那麼新的任務會被拒絕。ThreadPoolExecutor.AbortPolicy
:丟棄任務並拋出RejectedExecutionException
異常ThreadPoolExecutor.DiscardPolicy
:丟棄任務,但不拋出異常。ThreadPoolExecutor.DiscardOldestPolicy
:丟棄隊列最前面的任務,然後重新嘗試執行任務(循環此過程)ThreadPoolExecutor.CallerRunsPolicy
:由調用線程處理該任務
BlockingQueue
BlockingQueue
類型
ArrayBlockingQueue
:由數組結構組成的有界阻塞隊列LinkedBlockingQueue
:由鏈表結構組成的有界阻塞隊列PriorityBlockingQueue
:支持優先級排序的無界阻塞隊列DealyQueue
:使用優先級隊列實現的無界阻塞隊列SynchronousQueue
:不存儲元素的阻塞隊列LinkedTransferQueue
:由鏈表結構組成的無界阻塞隊列LinkedBlockingDeque
:由鏈表結構組成的雙向阻塞隊列
ArrayBlockingQueue
ArrayBlockingQueue
是定長阻塞隊列。原理是使用一個可重入鎖和Condition
進行併發控制(classic two-condition algorithm)。
參考資料: