關于線程池的源碼分析,在這裡也沒認真說明,後面單獨起一片文章進行研究。
1.大綱
線程池介紹
建立與停止線程池
常見的線程池特點與用法
任務太多,怎麼拒絕
鈎子方法
實作原理,源碼分析
使用線程池的主要點
一:介紹
1.重要性
使用中重要
面試中重要
2.池
線程可以複用
可以控制資源的總量
3.不使用線程池些的程式
這裡有兩個程式,隻粘貼進行循環對每個任務進行建立線程,并執行
4.為什麼使用線程池
反複的建立,開銷大
讓一部分的線程保持工作,反複的執行任務
過多的線程會占用太多的記憶體
使用少量的線程
5.線程池的好處
加快響應速度
更好的利用CPU,與記憶體。選擇合适的線程數
統一管理
6.使用場景
伺服器接收大量的請求
多個線程的建立
二:建立與停止線程池
1.線程池的構造函數的參數
corePoolSize:核心線程數,int
maxPoolSize:最大的線程數,int
keepAliveTime:存活時間,long
workQueue:任務存儲隊列,BlockingQueue
threadFactory:工廠類,ThreadFactory
Handler:拒絕政策,RejectedExecutionHandler
2.corePoolSize
線程池進行初始化的時候,線程池裡沒有任何的線程,線程池會等待有任務到來的時候,再進行建立新線程執行任務
3.macPoolSize
線程池有可能子啊核心線程數的基礎上,額外增加一些線程,但是這些新增加的線程數有一定的上限,這個就是最大量
如果超過了corePoolSize的時候,先将任務放到隊列中。
隊列中滿了,才會去看
4.添加線程的規則
如果線程小于corePoolSize的時候,即使線程有處于空閑狀态,也會繼續建立新的線程運作新的任務
如果等于大于corePoolSize,但是小于maxPoolSize,放入隊列
如果隊列已滿,并且線程小于maxPoolSize,建立新的線程
5.keepAliveTime
主要看是控制的是誰。
如果線程池的目前的線程數多于了corePoolSize,那麼多于的線程空閑時間超過keepAliveTime,将會被終止
減少資源消耗
6.ThreadFactory
新的線程預設使用Exectors.defaultThreadFactory(),建立的線程都在一個線程組,擁有相同的NORM_PRIORITY優先級,并且都不是守護線程
7.workQueue
工作隊列
最常見的隊列類型:
直接交換:SynchronousQueue,内部沒有容量
無界隊列:LinkedBlockingQueue
有界隊列:ArrayBlockingQueue
三:常見的線程池
1.FixedThreadPool建立
可以看見,corePoolSize與maxPoolSize是相等的
然後使用的是無界隊列。
由于傳遞進去的任務是沒有容量上限的,可能占用大量的記憶體,出現OOM
2.示範溢出
效果:
3.SingleThreadExector的使用
說明:
相比于FixedThreadPool,隻是corePoolSize與macPoolSize都是1,其他不變
4.也會出現OOM
5.CachedThreadPool
可緩存線程池,無界的線程池,可以自動回收多于線程的功能
其中,最大的線程數沒有限制,也是一個大的弊端。如果任務量過大,一樣會出現的是OOM
6.測試
建立了很多的線程
7.ScheduledThreadPool
支援定時與周期性的執行的線程池
核心線程是傳遞過去的,但是最大的核心線程數是INTEGER.MAX_VALUE
8.延遲一定時間之後運作
定時
9.周期性的運作
周期
10.總結
主要注意的是CacheDThreadPool與ScheduleThreadPool的對比。
CachedThreadPool為啥使用SynchronousQueue,因為有任務不需要進行存儲,直接交給線程執行就行了。
ScheduledThreadPool使用的是延遲隊列DelayedWorkQueue
四:線程池中的線程數量設定
1.計算密集型的
為cpu核心數的1~2倍
2.耗時IO型的
最佳線程數一般大于cpu很多倍。
以jvm線程監控顯示繁忙情況為依據,參考brain goetz推薦的計算方法
3.計算方法
cpu核心數 * (1+平均等待時間/平均工作時間)
五:停止線程池
1.shutdown
要線程中,會隊列中的線程任務都執行完成後,再進行停止
對拒絕新的任務
2.測試
可以發現,在執行一段時間後,就可以發現,真的不再進行接收任務了
3.isShutdown
可以知道線程被停止過了
先false,然後true
4.isTerminated
傳回是否真正的結束
效果:
5.awaitTermination
所有的任務都執行完畢,等待的時間到了,等待過程中被打斷都會傳回,否則阻塞。
說明:8秒内,如果關閉了線程,并且都執行完成傳回true,否則是false
6.shutdownNow
立刻關閉線程
存在傳回未執行的任務。
六:拒絕政策
1.拒絕時機
Executor關閉時
最大線程和隊列已滿
2.拒絕政策
AbsortPolicy:直接抛出異常
DiscradPolicy:默默丢棄
DiscardOldestPolicy:丢棄最老的任務
CallerRunsPolicy:誰送出的任務,則有誰進行運作,這樣可以降低送出速度
七:鈎子方法
1.說明
在任務的前後
日志,統計
2.暫停線程池
八:源碼
1.組成部分
線程池管理器
工作線程
任務隊列
任務接口
2.Exector家族
3.Exector
頂層接口,隻有一個方法
4.ExecuorService
繼承了Excetor,然後增加了幾個新的方法
初步的有了管理線程池的方法
5.Excetors
這是一個工具類
進入可以發現是使用ThreadPoolExector進行建立的線程
6.線程池實作任務複用的原理
execute:
添加到worker
進行運作:
九:線程池狀态
1.線程池狀态
Running:接收新任務并處理排隊任務
SHUTDOWN:不接受新任務,但是處理排隊任務
stop:不接受新任務,也不處理排隊任務,并中斷正在進行的任務
tidying:所有的任務都已經終結,workerCount為零時,線程就會轉為這個狀态,并且運作terminate()方法
TERMIMATED:運作完成
2.狀态值