Java 執行緒池使用 Executors 與 ThreadPoolExecutor
阿新 • • 發佈:2022-03-03
參考
介紹
Executors 工具類建立執行緒實現是呼叫的 ThreadPoolExecutor,但是隱藏了部分細節和引數設定。並且阿里巴巴程式碼規範也禁止使用 Executors 工具類建立執行緒池。
建立方法 | 描述 |
---|---|
Executors 工具類三種方法建立執行緒 | 堵塞等待執行(這裡不確定,可能有其他方法可以指定策略來堵塞或拋棄任務) |
ThreadPoolExecutor | 根據配置的拒絕策略來執行 |
Executors 方法
方法名 | 描述 |
---|---|
Executors.newSingleThreadExecutor() | 單一執行緒 |
Executors.newFixedThreadPool(int nThreads) | 指定執行緒數量 |
Executors.newCachedThreadPool() | 無限制,自動擴容與縮容(最大21億) |
ThreadPoolExecutor 介紹
-
引數列表
引數名 描述 int corePoolSize 核心執行緒數(不會被關閉) int maximumPoolSize 最大執行緒數(當佇列滿了之後,就會適當開啟執行緒) long keepAliveTime 當前執行緒數大於核心執行緒數,並且某些執行緒空閒一定時間後,會被關閉 TimeUnit unit 超時時間單位 BlockingQueue workQueue 指定使用的阻塞佇列型別與設定佇列的大小 ThreadFactory threadFactory 執行緒工廠,主要用來建立執行緒,預設為正常優先順序、非守護執行緒 RejectedExecutionHandler handler 拒絕策略,有四種 -
拒絕策略
策略名 描述 ThreadPoolExecutor.AbortPolicy 滿了(最大執行緒數+佇列大小)就報錯,但是已經進入的任務會執行完畢,這裡 shutdown() 方法要放在 finally 中 ThreadPoolExecutor.CallerRunsPolicy 滿了(最大執行緒數+佇列大小)拒絕/丟棄,直接在execute方法的呼叫執行緒中執行被拒絕的任務(main執行緒) ThreadPoolExecutor.DiscardOldestPolicy 滿了(最大執行緒數+佇列大小)就拒絕/丟棄最早進入並且未處理的任務 ThreadPoolExecutor.DiscardPolicy 滿了就拒絕/丟棄
Executors 不推薦
package pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @Author 夏秋初
* @Date 2022/3/3 14:22
*/
public class Test {
public static void main(String[] args) {
// 單一執行緒
// ExecutorService executorService = Executors.newSingleThreadExecutor();
// 固定執行緒數量
// ExecutorService executorService = Executors.newFixedThreadPool(2);
// 最大21億
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
executorService.execute(()->{
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
});
}
// 必須手動關閉
executorService.shutdown();
}
}
ThreadPoolExecutor 推薦
package pool;
import java.util.concurrent.*;
/**
* @Author 夏秋初
* @Date 2022/3/3 14:22
*/
public class Test2 {
public static void main(String[] args) {
// 執行緒池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
// 核心執行緒數(不會被關閉)
2,
// 最大執行緒數(當佇列滿了之後,就會適當開啟執行緒)
5,
// 當前執行緒數大於核心執行緒數,並且某些執行緒空閒一定時間後,會被關閉
10,
// 超時時間單位,當前例子是 10s
TimeUnit.SECONDS,
// 指定使用的阻塞佇列型別與設定佇列的大小
new LinkedBlockingDeque<Runnable>(3),
// 執行緒工廠,主要用來建立執行緒,預設為正常優先順序、非守護執行緒
Executors.defaultThreadFactory(),
/**
* 拒絕策略
* ThreadPoolExecutor.AbortPolicy 滿了就報錯,但是已經進入的任務會執行完畢,這裡 shutdown() 方法要放在 finally 中
* ThreadPoolExecutor.CallerRunsPolicy 滿了丟棄,直接在execute方法的呼叫執行緒中執行被拒絕的任務
* ThreadPoolExecutor.DiscardOldestPolicy 滿了就丟棄最早進入並且未處理的任務
* ThreadPoolExecutor.DiscardPolicy 滿了就丟棄
*/
new ThreadPoolExecutor.DiscardOldestPolicy()
);
try{
for (int i = 0; i < 20; i++) {
final int temp = i;
threadPoolExecutor.execute(()->{
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+temp);
});
}
}finally {
// 必須手動關閉
threadPoolExecutor.shutdown();
}
}
}
如果覺得文章對您有幫助,希望您能 關注+推薦 哦