線程池的工做主要是控制運行的線程數量,處理過程當中將任務放入隊列,而後在線程建立後啓動這些任務,若是線程數量超過了最大數量,那麼多餘的線程要排隊等候,等待其餘線程處理完畢,再從隊列中取出任務來執行。java
主要特色:線程複用
控制最大併發數
管理線程
小程序
java中的線程池是經過executor框架實現的,該框架中用到了Executor接口、Executors類、ThreadPoolExecutor類和ScheduledThreadPoolExecutor類。Executors和Executor的關係等同於從Collections與Collection和Arrays與Array,前者提供了許多輔助工具類能夠很方便的使用。 緩存
線程池的有5種,其中最經常使用的有如下三種多線程
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
複製代碼
主要特色:架構
定長線程池
,可控制線程最大併發數,超出的線程會在隊列中等待它使用的LinkedBolickingQueue
Executors.newSingleThreadExecutor() 只有一個線程 適用於單個任務現行執行的場景併發
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
複製代碼
主要特色:框架
一個單線程化
的線程池,他只會用惟一的工做線程來執行任務,保證全部任務按照指定順序執行它使用的LinkedBlockingQueue
Executors.newCachedThreadPool() 動態擴大線程數,適用於執行不少短時間異步的小程序或負載比較輕的服務異步
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
複製代碼
主要特色:ide
可緩存線程池
,若是線程池長度超過處理須要,可靈活回收空閒線程,若無可回收,則新建線程。以上三段代碼可知,線程池的構造都是從一個方法而來: ThreadPoolExecutor
工具
由以上三段代碼可知,在Exectors內部建立線程池ide時候,實際建立的都是一個ThreadPoolExecutor對象,只是對ThreadPoolExecutor構造方法,進行了默認值的設定。其構造方法以下:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
複製代碼
參數含義以下:
參數使用場景:
corePoolSize
時,建立新的線程運行這個任務corePoolSize
,那麼把任務放入隊列
中maximumPool
,那麼還要建立非核心線程
運行這個任務飽和拒絕策略
來執行。keepAliveTime
,線程池會判斷 若是當前運行線程數大於corePoolSize,則線程被銷燬當隊列滿了並且線程數已經達到maximumPoolSize,接下來的線程會受到拒絕策略的管控 拒絕策略有四種:
該任務須要大量的運算,而且沒有阻塞,CPU一直全速運行,CPU密集任務只有在真正的多核CPU上纔可能經過多線程加速
CPU密集型任務配置儘量少的線程數量:CPU核數+1個線程的線程池
IO密集型任務線程並非一直在執行任務,則應配置儘量多的線程,如CPU核數*2
根據阿里巴巴編碼規約,不容許使用Executors去建立,而是經過ThreadPoolExecutor的方式建立,這樣讓寫的同窗更加明確線程池的運行規則,避免資源耗盡的風險。 executors各個方法的弊端: