身為程式設計師我們對執行緒是再熟悉不過了,多執行緒併發算是Java進階的知識,用好多執行緒不容易有太多的坑。建立執行緒也算是一個"重"操作。建立執行緒的語句是new Thread()
咋一看好像就是new了一個物件。
沒錯是new了個物件,但是不僅僅是普通物件那樣在堆中分配了一塊記憶體,它還需要呼叫作業系統核心API,然後作業系統再為執行緒分配一些資源。所以較普通物件,執行緒就比較“重了”。所以我們要避免頻繁的建立和銷燬執行緒,還得控制一下執行緒的數量。執行緒池就是用來完成這一項使命的。
所以多執行緒就離不開執行緒池,所以要掌握多執行緒程式設計,執行緒池的瞭解必不可少。
執行緒池的設計就是採用生產者-消費者模式,執行緒池裡面的執行緒是消費者,我們塞給執行緒池的任務是生產者。可以理解成執行緒池就是火車站售票廳,執行緒池裡面的執行緒就是火車站售票廳視窗員工,我們去買票或者退票改簽就是給視窗員工任務也就是生產,然後視窗員工幫我們辦理業務,也就是消費。
一般我們是用ThreadPoolExecutor
來建立執行緒池,我找了裡面引數最多的構造器。
1、corePoolSize
按字面翻譯過來就是核心池大小,其實就是執行緒池保有的最小的執行緒數,這裡需要注意一下,初始化執行緒池的時候,除非呼叫prestartAllCoreThreads或者prestartCoreThread這兩個方法,這兩個方法分別是在無任務到來之前預建立所有核心執行緒或者建立一個執行緒。否則執行緒池初始化後沒任務進來前是沒有執行緒的。只有當任務來了才會建立執行緒。
所以這裡保有的核心數指的是,當執行緒池建立了這麼多的執行緒之後,會保留的不會被回收的執行緒數,超過corePoolSize的執行緒在一定時間之後就會被回收。
但是java1.6新增了一個allowCoreThreadTimeOut(boolean value)方法,當設為true時候,所有的執行緒都會超時回收,包括核心執行緒。
2、maximumPoolSize
最大執行緒數,也就是池裡面能有的最大的執行緒數量。也就是火車站售票廳視窗所有的視窗都有員工在服務。特別是在節假日的時候,基本上視窗都會開放。
3、keepAliveTime、TimeUnit
keepAliveTime就是存活時間,TimeUnit是時間單位,來表明keepAliveTime的數字是秒啊還是毫秒啊等等。 這兩個引數就是當我們執行緒池存在的執行緒數量超過corePoolSize時,如果有個執行緒已經空閒了keepAliveTime這麼長的時間,那麼這個空閒執行緒就要被回收了,就類似於出行高峰期過去了,售票廳視窗可以關閉幾個了。總不能都沒人了還開這麼多視窗把,浪費呀。
4、workQueue
工作佇列,是阻塞佇列。佇列儲存的也就是執行緒需要執行的Runnable,也就是任務。對應著就是去售票廳排隊的我們。
5、threadFactory
按名字翻譯過來就是執行緒工廠了,也就是我們可以搞個工廠,然後自定義如何建立執行緒,比如給執行緒set下名字啊等。然後執行緒池就會按照工廠定義的方式建立執行緒。就是如果不設定執行緒的名字的話,執行緒名可能就是什麼thread-1這樣的,對於我們排查問題不太方便,所以給個名字來標識一下比較好。
6、handler
這個是拒絕策略,也就是當執行緒池中所有的執行緒都在執行任務,並且工作佇列(是有界佇列)也排滿了,那再有任務提交就會執行拒絕策略。ThreadPoolExecutor提供了四種拒絕策略
1、ThreadPoolExecutor.AbortPolicy()
是預設的拒絕策略,會丟擲 RejectedExcecutionException。
2、ThreadPoolExecutor.CallerRunsPolicy()
讓提交任務的執行緒自己去執行這個任務。。好像這樣做挺有道理的..我沒空你自己搞去
3、ThreadPoolExecutor.DiscardOldestPolicy()
丟棄最老的任務,也就是工作佇列裡最前面的任務,丟棄了之後把新任務加入到工作佇列中...真的不公平啊
4、ThreadPoolExecutor.DiscardPolicy()
直接丟棄任務,並且不丟擲任何異常...假裝沒看到系列
除了這四種還可以自定義拒絕策略,建議自定義拒絕策略。因為更加的友好,可以設定成服務降級啊等操作。
注意
Java併發包還提供了Executors
,可以快速建立執行緒池,但是不推薦使用Executors
。因為Executors建立執行緒池都是預設使用無界佇列LinkedBlockingQueue
,在高負載的情況下容易OOM。所以建議使用有界佇列。
總結
所以執行緒池就是生產者-消費者模型的實現,執行緒池約束了執行緒的數量,也避免頻繁的建立和銷燬執行緒。工作佇列得存在使得任務有序的進行,完美!
如有錯誤歡迎指正! 個人公眾號:yes的練級攻略