線程池(ThreadPoolExecutor)

兩個好處:
1、線程可以重複利用,不用對同步任務進行不斷的創建銷燬
2、可以限制和管理資源,如線程
 
兩個結果組成:
Set workers 表示每個正在跑的線程,在run中,先是處理第一個Task,處理完後會從workQueue中嘗試拿到一個Task進行處理,如果沒有,結束(keepAliveTime可以調節結束的延時)、刪除這個worker
BlockingQueue<Runnable> workQueue 表示poolSize快要超出corePoolSize的時候,將對象放到阻塞隊列裏面去。如果阻塞隊列也放不進去,繼續放入workSet集合裏面,如果workset超出了maximumPoolSize,就只能RejectedExecutionHandler來處理
 
 
shutdown  如果這個worker空閒了(如果線程正在跑,會有runlock鎖住,然後tryLock返回false,就表示該worker不是空閒狀態),就interrupt這個worker對應的線程。(所以如果在run裏面做死循環的話,可以保證不是空閒的)
shutdownNow就不tryLock,直接執行worker.thread.interrupt()
 
ThreadPoolExecutor狀態
RUNNING          表示接受新任務,同時處理隊列中已有的任務
SHUTDOWN(shutdown)      表示不接受新任務,但會等剩餘任務(包括workqueue裏面的任務)都運行完
STOP(shutdownnow)               表示不接受新任務,不處理隊列中的任務,interrupt workers裏面的所有線程
TERMINATE      表示所有的線程已經終止
 
Executors.newFixedThreadPool(int nThreads)
創建的時候corePoolSize和maximumPoolSize一樣都是nThreads,queue爲LinkedBlockingQueue。也就是說,如果workset放滿了,就放到queue裏面等待,如果queue也放滿了(基本不會出現這種情況,沒設值,默認爲Integer.MAX_VALUE),就只能RejectExecutionHandler來處理。
Executors.newCachedThreadPool()
創建的時候corePoolSize爲0,maximumPoolSize爲Integer.MAX_VALUE,queue爲SynchronousQueue。也就是說,先將任務放入queue裏面,如果workset裏面的poolsize爲0,會在workset裏面創建一個空任務去抓取SynchronousQueue裏面的等待任務。如果不爲0,就等待任務workset裏面的某個任務先處理完了再去抓。如果有新任務進來,先判斷是否能放入queue(這裏是SynchronousQueue,只能放一個),如果不能,就直接放入workset裏面。
 
兩種線程池缺點:
fixedThreadPool會出現內存不可控制的情況,因爲LinkedBlockingQueue沒有數量限制。
cachedThreadPool更容易出現內存不可控制,因爲maximumPoolSize爲Integer.MAX_VALUE,很可能會創建許多線程(線程所佔的內存比一個任務對象所佔內存肯定大很多)。所以它適合於任務小,處理速度非常快的場景
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章