談談線程池,談談對ThreadPoolExecutor的理解

爲什麼用線程池,優勢

線程池做的工作主要是控制運行的線程的數量處理過程中將任務放入隊列然後在線程創建後啓動這些任務如果線程數量超過了最大數量超出數量的線程排隊等待等其它線程執行完畢,再從隊列中取出任務來執行

他的主要特點爲:線程複用;控制最大併發數;管理線程。

第一:降低資源消耗。通過重複利用已創建的線程降低線程創建和銷燬造成的消耗。
第二:提高響應速度。當任務到達時,任務可以不需要的等到線程創建就能立即執行。
第三:提高線程的可管理性。線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一的分配,調優和監控。

線程池如何使用

架構說明

Java 中的線程池是通過 Executor 框架實現的,該框架中用到了 ExecutorExecutorsExecutorServiceThreadPoolExecutor 這幾個類。
在這裏插入圖片描述

編碼實現

瞭解

Executors.newScheduledThreadPool()
Java8 新出:Executors.newWorkStealingPool(int parallelism) ,Java8 新增,使用目前機器上可用的處理器作爲它的並行級別

重點

Ⅰ、Executors.newFixedThreadPool(int nThreads) 適用:執行長期的任務,性能好很多
在這裏插入圖片描述
主要特點如下:
1、創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
2、newFixedThreadPool 創建的線程池 corePoolSizemaximumPoolSize 值是相等的,它使用的 LinkedBlockingQueue

Ⅱ、Executors.newSingleThreadExecutor() 適用:一個任務一個任務執行的場景
在這裏插入圖片描述
主要特點如下:
1、創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序執行。
2、newSingleThreadExecutorcorePoolSizemaximumPoolSize 都設置爲1,它使用的 LinkedBlockingQueue

Ⅲ、Executors.newCachedThreadPool() 適用:執行很多短期異步的小程序或者負載較輕的服務器
在這裏插入圖片描述
主要特點如下:
1、創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。
2、newCacheThreadPoolcorePoolSize 設置爲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 的大小
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章