ThreadPoolExecutor筆記

class ThreadPoolExecutor 異步

    extends AbtractExecutorService spa

    能提高大量異步任務的執行效率,提供了線程等資源的管理,而且維護了一些基本的統計信息。 線程

    兩個重要的參數:corePoolSizemaximumPoolSize。當一個任務被提交時,若是正在運行的線程數少於corePoolSize,無論線程是否空閒,則建立新的線程處理該任務請求;若是線程數大於corePoolSize,且小於maximumPoolSize,只有在任務隊列已滿時才建立新的線程。設置corePoolSize==maximumPoolSize,能夠建立一個固定大小的線程池;也能夠設置maximumPoolSizeInteger.MAX_VALUErest

    默認只有新任務來的時候纔會建立和啓動線程,也能夠經過重寫方法prestartCoreThreadprestartAllCoreThreads,能夠用一個非空的隊列來在線程池建立的時候預啓動線程。 隊列

    線程的建立默認是經過defaultThreadFactory,被建立的線程有相同的優先級(NORM_PRIORITY),線程工廠指定的線程名,相同的線程組,非守護線程等。用戶能夠實現本身的ThreadFactory來指定上述屬性。線程必須有「modifyThread」運行時權限,若是沒有該權限,一些服務將沒法使用,如運行時的配置改變沒法生效,線程池關閉不必定成功等。 資源

    若是線程池當前的線程數大於corePoolSize,多餘的線程在空閒時間超過keepAliveTime後會被終止;若是設置allowCoreThreadTimeOut(true),則該限制也一樣應用於core threadsget

    使用BlockingQueue來存聽任務隊列。當新任務來時: it

    1. 若是小於corePoolSize的線程數執行,則建立新線程; io

    2. 若是大於等於corePoolSize的線程數執行,則新任務添加到隊列中; class

    3. 若是任務請求沒法添加到隊列中,建立新線程,當超過maximumPoolSize時任務會被拒絕。

一般有三種任務隊列策略:

    1. SynchronousQueue:不保存任務,直接將任務提交線程處理。能夠避免一組相互依賴的請求內部可能出現的鎖。一般要求設置maximumPoolSize爲最大;

    2. LinkedBlockingQueue:隊列無最大上限。建立的線程數不會超過corePoolSizemaximumPoolSize在這種狀況下不起做用。適合相互獨立的線程,能夠用來緩衝突發的大量請求;

    3. ArrayBlockingQueue:使用有限的maximumPoolSize,避免資源的耗盡;但協調和控制的難度增大,須要在隊列大小和線程池大小之間作平衡。使用大的隊列和小的線程池,能夠最小化cpu使用和系統資源,以及上下文切換消耗,但致使低吞吐量。若是任務頻繁的阻塞(如I/O),系統能夠分配比用戶容許的更多的線程時間。使用小的隊列一般要求大的線程池,能夠保持CPU忙碌,但可能帶來更大的調度開銷,以至於較低吞吐量。

    當線程池已經關閉,或者使用了有限的maximumPoolSize和隊列而且已飽和,則新的任務將會被拒絕。這時將調用rejectedExecution。有四種預約義的線程拒絕策略:

    1. ThreadPoolExecutor.AbortPolicy,拋出RejectedExecutionException

    2. ThreadPoolExecutor.CallerRunsPolicy,(the thread that invokes execute itself runs the task)提供了一種簡單的反饋控制機制來下降任務提交的頻率;

    3. ThreadPoolExecutor.DiscardPolicy,任務被拋棄;

    4. ThreadPoolExecutor.DiscardOldestPolicy,隊列頂端的任務被拋棄,而且重試任務執行;

    除了預約義,也能夠定義和使用其它類型的RejectedExecutionHandler

    同時提供了可被重寫的方法beforeExecuteafterExecute,用於控制運行環境。此外terminated能夠被重寫,用於線程池中止時須要處理的過程。若是hook或回調方法執行過程當中拋出異常,則內部的worker線程可能運行失敗而且意外終止。


abstract class AbstractExecutorService

        implements ExecutorService

     ExecutorService的默認實現。

    經過newTaskFor實現了submitinvokeAllinvokeAny


interface ExecutorService

        implements Executor

    shutdown容許以前提交的任務在停止以前執行完成,再也不接受新任務,但不等待任務執行完成;

    shutdownNow而且嘗試中止當前執行的任務,阻止等待的任務執行,返回等待執行的任務列表,不保證必定可以關閉執行中的任務(例如調用interrupt中斷線程有可能失敗);

    isShutdown:

    isTerminated: 調用shutdown/shutdownNow以後,若是全部任務都完成了則返回true

    awaitTermination(timeout,unit): shutdown請求後,阻塞到全部任務都執行完成或者超時,或者當前線程被中斷。若是是超時,返回false,若是該executor停止返回true

    <T> Future<T> submit(Callable<T> task): Future模式,提交後返回一個Future,經過調用Futureget方法獲取實際任務成功執行的返回值;

    <T> Future<T> submit(Runnable taskT result):

    Future<?> submit(Runnable task);

    invokeAll(tasks): 執行給定的一組任務,返回Future


interface Executor

    將任務提交與任務執行的機制解耦。不顯式的建立線程,而是用例如executor.execute(new RunnableTask1());的形式。

    不嚴格要求異步執行,能夠直接在調用者線程中執行:

class DirectExecutor implements Executor {

    public void execute(Runnable r) {

        r.run();

    }

}

但一般是爲每一個任務開啓一個新的線程。

class ThreadPerTaskExecutor implements Executor {

    public void execute(Runnable r) {

        new Thread(r).start();

    }

}

    Executor只有一個execute(Runnable command);方法,要求若是任務不能被接受執行,則拋出RejectedExecutionException,若是commandnull,拋出NullPointerException異常。

相關文章
相關標籤/搜索