【java】java8線程池ThreadPoolExecutor淺析

寫在前面

本文是我自己對ThreadPoolExecutor的簡單理解,是看了ThreadPoolExecutor的源碼和orcle官網的文檔之後的體會,並不是一板一眼的翻譯官網,也建議大家結合學習。

如果有誤,歡迎大家批評指正哈~

官網網址

Java™ Platform Standard Ed. 8 Class ThreadPoolExecutor

線程池ThreadPoolExecutor解決的問題:

提高大量同步任務的執行性能;
維護一些基本的數據,比如已完成的任務數

參數:

1.corePoolSize & maximumPoolSize
  1. 當前線程數少於cirePoolSize,一定會開新的線程。
  2. 當前線程數大於corePoolSize,少於maximumOiikSuze,只有在隊列曼聯的時候纔會開新的線程。
  3. 一般是構建的時候初始化,但是可以通過set方法動態更改。
2.預先啓動核心線程池的方法

prestartAllCoreThreads(),prestartAllCoreThreads()

3.生存時間

若當前線程數超過了核心線程池的線程數,多餘的線程會被terminated掉

4.隊列

任何類,只要實現了BlockingQueue接口,就能被用來傳輸和持有提交的任務。該隊列與線程池的規模有關:

  1. 如果當前運行的線程數<corePoolSize,線程被創建,不放入隊列
  2. 如果當前運行的線程數>=corePoolSize,線程被放入隊列
  3. 如果當前運行加入會使得總線程數>maximumPoolSize,任務被拒絕

實現了BlockingQueue的類
( 注意:根據阿里編程規範:不建議用Executors.newFixedThreadPool()、Executors.newCachedThreadPool()和Executors.newSingleThreadExecutor(),建議new ThreadPoolExecutor(…),因爲Executors的幾個方法都是對ThreadPoolExecutor進行了封裝,一個好的程序員應該瞭解其底層實現呦):

1. SynchronousQueue:

  • 該隊列不保留任何任務,統統直接扔給線程。要是線程池的線程個數超maximumPoolSize了,就拒絕任務。
  • Executors.newCachedThreadPool()就用的這個。所以java編程思想p657裏會說:newCachedThreadPool通常會創建與所需數量相同的線程。在newCachedThreadPool的實現中,maximumPoolSize=Interger.MAX_VALUE,可以看成允許創建無限長的線程啦
  • Executors.newCachedThreadPool()缺點是:當提交的任務過多的時候,會創建大量的線程,導致OOM/

2. LinkedBlockingQueue:

  • 如果不預定義容量,該隊列會建立一個無限長的隊列(其實長度是Interger.MAX_VALUE,可以看成無限長啦)。
  • 任務什麼情況下會被放入隊列裏呢?當運行的任務數>corePoolSize時,就會被放入。而因爲這個隊列是無限長的,所以maximumPoolSize屬性不起任何作用了。
  • 所以我們看一下newFixedThreadPool的實現:
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
  • Executors.newFixedThreadPool()和Executors.newSingleThreadExecutor()就用的這個,適用於類似網頁訪問這種,訪問量可能大到無法估計的情況。使用該方法定義的線程池,運行的線程數是固定的。
    3. ArrayBlockingQueue
    看不下去了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章