爲什麼用線程池,優勢
線程池做的工作主要是控制運行的線程的數量,處理過程中將任務放入隊列,然後在線程創建後啓動這些任務,如果線程數量超過了最大數量超出數量的線程排隊等待,等其它線程執行完畢,再從隊列中取出任務來執行。
他的主要特點爲:線程複用;控制最大併發數;管理線程。
第一:降低資源消耗。通過重複利用已創建的線程降低線程創建和銷燬造成的消耗。
第二:提高響應速度。當任務到達時,任務可以不需要的等到線程創建就能立即執行。
第三:提高線程的可管理性。線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一的分配,調優和監控。
線程池如何使用
架構說明
Java 中的線程池是通過 Executor 框架實現的,該框架中用到了 Executor,Executors,ExecutorService,ThreadPoolExecutor 這幾個類。
編碼實現
瞭解
Executors.newScheduledThreadPool()
Java8 新出:Executors.newWorkStealingPool(int parallelism) ,Java8 新增,使用目前機器上可用的處理器作爲它的並行級別
重點
Ⅰ、Executors.newFixedThreadPool(int nThreads) 適用:執行長期的任務,性能好很多
主要特點如下:
1、創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
2、newFixedThreadPool 創建的線程池 corePoolSize 和 maximumPoolSize 值是相等的,它使用的 LinkedBlockingQueue;
Ⅱ、Executors.newSingleThreadExecutor() 適用:一個任務一個任務執行的場景
主要特點如下:
1、創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序執行。
2、newSingleThreadExecutor 將 corePoolSize 和 maximumPoolSize 都設置爲1,它使用的 LinkedBlockingQueue。
Ⅲ、Executors.newCachedThreadPool() 適用:執行很多短期異步的小程序或者負載較輕的服務器
主要特點如下:
1、創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。
2、newCacheThreadPool 將 corePoolSize 設置爲0,將maximumPoolSize 設置爲 Integer.MAX_VALUE,使用的 SynchronousQueue,也就是說來了任務就創建新線程運行,當線程空閒超過60秒,就銷燬線程。
ThreadPoolExecutor
線程池的幾個重要參數介紹(7 大參數)
- 1、corePoolSize:線程池中的常駐核心線程數
-
1、在創建了線程池後,當有請求任務來之後,就會安排池中的線程去執行請求任務,近似理解爲今日當值線程
-
2、當線程池中的線程數目達到 corePoolSize 後,就會把到達的任務放到緩存隊列當中;
-
- 2、maximumPoolSize:線程池能夠容納同時執行的最大線程數,此值必須大於等於1
- 3、keepAliveTime:多餘的空閒線程的存活時間。當前線程池數量超過 corePoolSize 時,當空閒時間達到 keepAliveTime 值時,多餘空閒線程會被銷燬直到只剩下 corePoolSize 個線程爲止
- 默認情況下:
只有當線程池中的線程數大於 corePoolSize 時 keepAliveTime 纔會起作用,直到線程池中的線程數不大於 corePoolSize。
- 默認情況下:
- 4、unit:keepAliveTime 的單位
- 5、workQueue:任務隊列,被提交但尚未被執行的任務。
- 6、threadFactory:表示生成線程池中工作線程的線程工廠,用於創建線程一般用默認的即可。
- 7、handler:拒絕策略,表示當隊列滿了並且工作線程大於等於線程池的最大線程數(maximumPoolSize)時如何來報道
線程池的底層工作原理
以下重要:以下重要:以下重要:以下重要:以下重要:以下重要:
- 1、在創建了線程池後,等待提交過來的任務請求。
- 2、當調用 execute() 方法添加一個請求任務時,線程池會做如下判斷:
- 2.1、如果正在運行的線程數量小於 corePoolSize,那麼馬上創建線程運行整個任務;
- 2.2、如果正在運行的線程數量大於或等於 corePoolSize,那麼將這個任務放入隊列;
- 2.3、如果這時候隊列滿了且正在運行的線程數量還小於 maximumPoolSize,那麼還是要創建非核心線程立刻運行這個任務;
- 2.4、如果隊列滿了且正在運行的線程數量大於或等於 maximumPoolSize,那麼線程池會啓動飽和拒絕策略來執行。
- 3、當一個線程完成任務時,它會從隊列中取下一個任務來執行。
- 4、當一個線程無事可做超過一定的時間(keepAliveTime)時,線程池會判斷:
如果當前運行的線程數大於 corePoolSize,那麼這個線程就被停掉。
所以線程池的所有任務完成後它最終會收縮到 corePoolSize 的大小。