在 Executoors 中的 newChachedThreadPool, newFixedThreadPool, newScheduledThreadExecutor 的工廠方法返回的都是 ThreadPoolExecutor 對象。若是默認的執行策略不能知足需求,能夠經過 ThreadPoolExecutor 的構造函數進行實例化,根據本身的需求定製。 html
)ThreadPoolExecutor(int corePoolSize,//線程池基本大小
int maximumPoolSize, //線程池最大尺寸
long keepAliveTime, //線程空閒後的存活時間
TimeUnit unit,
BlockingQueue<Runnable> workQueue, //任務隊列
ThreadFactory threadFactory, //線程工廠
RejectedExecutionHandler handler) //飽和策略
複製代碼
newFixedThreadPool 工廠方法將線程池的基本大小和最大大小都設置爲參數中指定的值,並且建立的線程池不會超時。java
newCachedThreadPool工廠方法將線程池的最大大小設置爲Integer.MAX_VALUE,將基本大小設置爲0,並將超時設置爲1分鐘,這種方法建立出來的線程池能夠被無限擴展,而且當需求下降時會自動收縮。git
使用BlokcingQueue來保存等待執行的任務。基本的隊列有無界隊列,有界隊列和同步移交。隊列的選擇和線程池的其餘配置參數有關。編程
newFixedThreadPool 和 newSingleThreadExecutor 在默認狀況下使用一個無界的LinkedBlockingQueue。若是全部工做者線程都處於忙碌狀態, 那麼任務將在隊列中等待。緩存
有界隊列包括ArrayBlockingQueue以及有界的LinkedBlockingQueue和PriorityBlockingQueue。在使用有界隊列時,隊列的大小須要和線程池的大小一塊兒調節。線程池小而隊列較大,有助於減小內存使用量,下降CPU的使用率,同時還能夠減小上下文切換,可是可能會限制吞吐量。併發
對於很是大或無界的線程池,能夠經過SynchronousQueue來避免任務排隊,以及直接將任務從生產者移交給工做者線程。這個隊列的put方法會阻塞,直到有線程準備從隊列裏面take,因此本質上SynchronousQueue並非Queue,它不存儲任何東西,它只是在移交東西,是一種在線程之間進行移交的機制。要將一個任務放到其中,必須有另外一個線程正在等待接受這個元素。若是沒有線程正在等待,而且線程池的當前大小小於最大值,那麼ThreadPoolExecutor將建立一個新的線程,不然這個任務獎盃拒絕。在 newCachedThreadPool中採用了SynchronousQueue。函數
當有界對壘被填滿後,飽和策略開始發揮做用。經過setRejectedExecutionHandler來修改。有如下四種飽和策略。spa
線程池在建立線程時,經過線程工廠方法來完成。在默認的ThreadFactory接口中只定義了一個方法newThread,每當建立新線程時都會調用這個方法。能夠本身建立一個類實現默認的ThreadFactory接口來定製本身的線程工廠。線程
ThreadPoolExecutor是能夠擴展的,它提供了幾個能夠在子類中改寫的方法:beforeExecute, afterExecute, terminated。在執行任務的線程中將調用beforeExecute和afterExecute方法。不管是正常返回仍是拋出異常,afterExecute都被調用。若是beforeExecute拋出一個RuntimeException,任務將不被執行,afterExecute也不會調用。rest