文章目錄
- 一、`Executor` 簡介
- (1)`Executors.WorkStealingPool`
- (2)`Executors.newCachedThreadPool`
- (3)`Executors.newScheduledThreadPool`
- (4)`Executors.newSingleThreadPool`
- (5)`Executors.newFixedThreadPool`
- 二、詳細
Java 中提供
Executor
架構用來幫助使用者使用線程池
線程池的作用:
- 複用線程、控制最大并發數等
- 實作任務線程隊列緩存政策和拒絕政策
- 實作某些與時間相關的功能,如定時執行、周期執行等
- 隔離線程環境
一、 Executor
簡介
Executor
如圖:
通過Executor架構的根據類Executors,可以建立三種基本的線程池:
-
ForkJoinPool
-
ThreadPoolExecutor
-
ScheduledThreadPoolExecutor
核心方法如下:
(1) Executors.WorkStealingPool
Executors.WorkStealingPool
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
JDK8 引入,建立持有足夠線程的線程池支援給定的并行度,并通過使用多個隊列減少競争,此構造方法中把 CPU 數量設定為預設的并行度
(2) Executors.newCachedThreadPool
Executors.newCachedThreadPool
CachedThreadPool是一個會根據需要建立新線程的線程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue());
SynchronousQueue
是一種阻塞隊列,其中每個插入操作必須等待另一個線程的對應移除操作 ,反之亦然。
corePoolSize
是 0,
maximumPoolSize
都最大,無界的。
keepAliveTime
為60秒,空閑線程超過 60秒 會被終止。
适用場景:适用于短期異步的小任務,或負載教輕的伺服器
(3) Executors.newScheduledThreadPool
Executors.newScheduledThreadPool
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5);
//可以直接執行
executor.execute(new JobTaskR("executor", 0));
executor.execute(new JobTaskR("executor", 1));
System.out.println("5S後執行executor3");
//隔5秒後執行一次,但隻會執行一次。
executor.schedule(new JobTaskR("executor", 3), 5, TimeUnit.SECONDS);
System.out.println("開始周期排程");
//設定周期執行,初始時6S後執行,之後每2s執行一次
executor.scheduleAtFixedRate(new JobTaskR("executor", 4), 6, 2, TimeUnit.SECONDS);
scheduleAtFixedRate
或者
scheduleWithFixedDelay
方法,它們不同的是前者以固定頻率執行,後者以相對固定延遲之後執行。
線程數最大至
Integer.MAX_VALUE
,存在
OOM
風向。
支援定時及周期性任務執行。
ScheduleThreadPoolExecutor
和
Timer
類似,可以設定延時執行或周期執行,但比
Timer
有更多的功能,
ScheduledExecutorService
更安全,功能更強大。
Timer
和
TimerTask
隻建立一個線程,任務執行時間超過周期會産生一些問題。Timer建立的線程沒有處理異常,是以一旦抛出非受檢異常,會立刻終止。
與
newCachedThreadPool
差別是不回收工作線程
(4) Executors.newSingleThreadPool
Executors.newSingleThreadPool
核心線程池數量和最大數量
corePoolSize
都設定為1
maximumPoolSize
适用于需要保證順序執行的場景
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
适用場景:保證順序執行
(5) Executors.newFixedThreadPool
Executors.newFixedThreadPool
可重用固定線程數的線程池
// 擷取fixedThreadPool
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(paramInt);
// 内部會調用下面的方法,參數 corePoolSize、maximumPoolSize、keepAliveTime、workQueue
return new ThreadPoolExecutor(paramInt, paramInt, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
FixedTheadPool
設定的線程池大小和最大數量一樣;
keepAliveTime
為0,代表多餘的空閑線程會立刻終止;儲存任務的隊列使用
LinkedBlockingQueue
,當線程池中的線程執行完任務後,會循環反複從隊列中擷取任務來執行。
FixedThreadPool
适用于限制目前線程數量的應用場景,适用于負載比較重的伺服器。