Java 線程池 ThreadPoolExecutor 的那些事兒

線程池基礎知識

ThreadPoolExecutor : 一個線程池
Executors : 線程池工廠,經過該類能夠取得一個擁有特定功能的線程池
ThreadPoolExecutor類實現了Executor接口,所以經過這個接口,任何的Runnable對象均可以被ThreadPoolExecutor線程池調度。
常見的線程池類型java

  • public static ExecutorService newFixedThreadPool(int nThreads)

    返回一個固定線程數量的線程池。線程數量始終不變。當有空閒線程時,當即執行;若沒有,新線程暫存在一個任務隊列中,待線程空閒,便開始處理任務隊列中的任務。函數

  • public static ExecutorService newSingleThreadExecutor()

    返回一個只有一個線程的線程池。新線程過來存放在任務隊列中,線程空閒時,處理任務隊列中的任務。性能

  • public static ExecutorService newCachedThreadPool()

    返回一個能夠根據實際狀況調整線程數量的線程池。線程的進程數不肯定,可是若是有空閒線程能夠複用,則會優先使用該線程。若是全部線程都在工做,又有新的任務提交,那麼就會建立新的線程執行任務。全部線程在當前任務完成以後,將返回線程池進行服用。線程

  • public static ScheduledExecutorService newSingleThreadScheduldExecutor()

    返回一個ScheduledExecutorService對象,線程池大小爲1。在某個固定的延時以後執行,或者週期性執行某個任務code

  • public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

    和上面同樣,可是能夠指定線程數。對象


核心線程池的內部實現

對於核心的幾個線程池,其內部實現都是使用了ThreadPoolExecutor實現。接口

  • public static ExecutorService newFixedThreaPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads,nThreads,
                                     0L,TimeUnit.SECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
  • public static ExecutorService newSingleThreadExecutor() {
        return new ThreadPoolExecutor(1,1,
                                     0L,TimeUnit.SECONDS,
                                     new LinkedBlockingQueue<Runnable>());
    }
  • public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0,Integer.MAX_VALUE,
                                     60L,TimeUnit.SECONDS,
                                     new SynchronousQueue<Runnable>());
    }

看一下ThreadPoolExecutor最重要的構造函數隊列

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long KeepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

函數的參數含義以下:進程

  • corePoolSize:線程池中的線程數量。
  • maximumPoolSize:線程池中的最大線程數量。
  • keepAliveTime:當線程池數量超過corePoolSize時,多餘的空閒線程的存活時間。
  • unitkeepAliveTime的單位。
  • workQueue:任務隊列,被提交可是還沒有被執行的任務。
  • threadFactory:線程工廠,用於建立線程,通常用默認的就行。
  • handler:拒絕策略。當任務太多來不及處理,如何拒絕任務。

在上面的參數中,其餘的都好理解,主要是workQueuehandler須要重點說起一下。it


workQueue 任務隊列講解

workQueue 指被提交可是還沒有被執行的任務隊列,它是一個BlockingQueue接口的對象,僅用於存在Runnable對象。根據隊列功能分類,在ThreadPoolExecutor的構造函數中可使用如下幾種BlockingQueue

  • 直接提交的隊列SynchronousQueueSychronousQueue是一個特殊的BlockingQueueSychronousQueue沒有容量,每個插入操做都要等待一個相應的刪除操做,反之,一個刪除操做都要等待對應的插入操做。若是使用SychronousQueue,提交的任務不會被真實的保存,而老是將新任務提交給線程執行,若是沒有空閒線程,那麼嘗試建立新的線程,若是進程數量已經達到最大值,則執行拒絕策略。所以,使用SychronousQueue一般要設置很大的maximumcorePoolSize,不然很容易執行拒絕策略。
  • 有界的任務隊列ArrayBlockingQueue:特色:如有新的任務須要執行,若是線程池的實際線程小於corePoolSize,則會優先建立新的線程;若大於corePoolSize,則會將新任務加入到等待隊列。若是等待隊列已滿,沒法加入,則在總線成熟不大於maximumPoolSize的前提下,建立新的線程執行任務。若大於,則執行拒絕策略。
  • 無界的任務隊列LinkedBlockingQueue:特色:如有新的任務須要執行,若是線程池的實際線程小於corePoolSize,則會優先建立新的線程;若大於corePoolSize,進入等待隊列。
  • 優先任務隊列PriorityBlockingQueue:能夠根據任務自身的優先級順序前後執行。

handler拒絕策略講解

JKD 內置的拒絕策略都是經過實現RejectedExecutionHandler接口實現的,具體以下:

  • AbortPolicy策略:直接拋出異常,阻止系統正常工做;
  • CallerRunsPolicy策略:只要線程未關閉,直接在調用者線程中,運行當前被丟棄的任務。warning:有可能性能會急劇降低
  • DiscardOledstPolicy策略:丟棄一個最老的請求,並嘗試再次提交當前的任務。
  • DiscardPolicy策略:丟棄沒法處理的請求,不予任何處理,不作出任何的提示。
相關文章
相關標籤/搜索