線程池的作用:
第一:可以減少資源的消耗. 因為線程的創建和銷毀比較消耗資源, 利用線程池就可以不用頻繁的創建和銷毀線程, 直接用, 用完也不用銷毀, 重復利用, 就能達到降低資源消耗的目的.
第二: 方便管理. 利用線程池可以統一管理, 統一分配.
線程池創建:(七大參數說明)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
corePoolSize :核心線程數. 代表線程池創建的常駐線程數, 這些線程創建之后一直存在.
maxinumPoolSize: 最大線程數, 代表能創建的最多的線程數量. 大於等於核心線程數, 這個在核心線程數不夠用的情況下, 還可以增加一些臨時線程, 但是總數不能超過最大線程數.
keepAliveTime, 臨時線程的空閑存活時間, 核心線程不會消除, 但是新增的臨時線程空閑時間(注意是空閑時間) 超過設定的時間就需要要消除,. unit是時間單位.
workQueue: 工作隊列. 任務排隊的隊列, 共分為四種:
第一種: ArrayBlockingQueue , 基於數組, FIFO排序, 新來的放隊尾, 數組是有界的, 防止資源耗盡.
第二種: LinkedBlockingQuene, 基於鏈表, FIFO拍尋, 無界. 多少線程都能放進去, 用這種隊列時, maxPoolSize不起作用
第三種:SynchronousQuene, 不緩存任務的阻塞隊列, 新任務直接調度執行, 如果沒有可用線程就創建, 直到maxPoolSize之后, 就執行拒絕策略
第四種: PriorityBlockingQueue, 有優先級的無界阻塞隊列.
threadFactory : 線程工廠, 可以用來設定線程名, 是否為守護線程等特性(默認的線程名都是thread-1等字樣, 分布式服務器時不易區分)
handler:拒絕策略. 任務到達最大限制, 線程池中的線程數量也到最大限制, 再進來的新任務就只能執行拒絕策略了. jdk中有4種拒絕策略:
第一種: CallerRunsPolicy. 直接執行新來的任務的run方法,
第二種: AbortPolicy, 直接丟棄新來的任務, 拋出異常: RejectedExecutionException
第三種: DiscardPolicy, 直接丟棄新來的任務, 不拋異常.
第四種: DiscardOldestPolicy. 丟棄隊列種原有的最早的那個任務, 把新來的任務放入隊列.
線程池使用
線程池執行任務時,
先判斷核心線程是否已滿,
如果核心線程沒滿, 則創建核心線程來執行任務.
如果核心線程已滿, 則查看任務隊列:
如果任務隊列沒滿, 就放入任務隊列,
如果任務隊列已滿, 則查看是否到達最大線程數:
如果線程總數沒有達到最大線程數, 創建臨時線程,
如果線程總數達到最大線程數, 就執行拒絕策略.
簡單來說就依次查看:
核心線程 (核心線程滿了)==> 任務隊列,
任務隊列 (任務隊列滿了) ==> 創建臨時線程,
創建臨時線程 (線程總數超了) ==> 執行拒絕策略