```java
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**:線程池的核心線程數,一般情況下不管有沒有任務都會一直在線程池中一直存活,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 設置為 true 時,閑置的核心線程會存在超時機制,如果在指定時間沒有新任務來時,核心線程也會被終止,而這個時間間隔由第3個屬性 keepAliveTime 指定。
- **maximumPoolSize**:線程池所能容納的最大線程數,當活動的線程數達到這個值后,后續的新任務將會被阻塞。
- **keepAliveTime**:控制線程閑置時的超時時長,超過則終止該線程。一般情況下用于非核心線程,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 設置為 true時,也作用于核心線程。
- **unit**:用于指定 keepAliveTime 參數的時間單位,TimeUnit 是個 enum 枚舉類型,常用的有:TimeUnit.HOURS(小時)、TimeUnit.MINUTES(分鐘)、TimeUnit.SECONDS(秒) 和 TimeUnit.MILLISECONDS(毫秒)等。
- **workQueue**:線程池的任務隊列,通過線程池的 execute(Runnable command) 方法會將任務 Runnable 存儲在隊列中。
- **threadFactory**:線程工廠,它是一個接口,用來為線程池創建新線程的。
- **handler**:拒絕策略,所謂拒絕策略,是指將任務添加到線程池中時,線程池拒絕該任務所采取的相應策略。
> newCachedThreadPool是一個可根據需要創建新線程的線程池,但是在以前構造的線程可用時將重用它們。對于執行很多短期異步任務的程序而言,這些線程池通常可提高程序性能。調用 execute() 將重用以前構造的線程(如果線程可用)。如果現有線程沒有可用的,則創建一個新線程并添加到池中。終止并從緩存中移除那些已有 60 秒鐘未被使用的線程。因此,長時間保持空閑的線程池不會使用任何資源。注意,可以使用 ThreadPoolExecutor 構造方法創建具有類似屬性但細節不同(例如超時參數)的線程池。
```java
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
```
> newSingleThreadExecutor 創建是一個單線程池,也就是該線程池只有一個線程在工作,所有的任務是串行執行的,如果這個唯一的線程因為異常結束,那么會有一個新的線程來替代它,此線程池保證所有任務的執行順序按照任務的提交順序執行。
```java
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
```
> newFixedThreadPool 創建固定大小的線程池,每次提交一個任務就創建一個線程,直到線程達到線程池的最大大小,線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執行異常而結束,那么線程池會補充一個新線程。
```java
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
```
> newScheduledThreadPool 創建一個大小無限的線程池,此線程池支持定時以及周期性執行任務的需求。
```java
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
```
## 線程池提供了四種拒絕策略:
- AbortPolicy:直接拋出異常,默認策略;
- CallerRunsPolicy:用調用者所在的線程來執行任務;
- DiscardOldestPolicy:丟棄阻塞隊列中靠最前的任務,并執行當前任務;
- DiscardPolicy:直接丟棄任務;
## 線程池弊端:
`Executor`提供的四個靜態方法創建線程池,但是阿里規約卻并不建議使用它。
Executors各個方法的弊端:
- `newFixedThreadPool`和`newSingleThreadExecutor`:主要問題是堆積的請求處理隊列可能會耗費非常大的內存,甚至OOM。
- `newCachedThreadPool`和`newScheduledThreadPool`:主要問題是線程數最大數是Integer.MAX_VALUE,可能會創建數量非常多的線程,甚至OOM。
```java
// 隨項目初始化創建定時任務
public void initTest() {
// 創建固定大小的線程池,可以延遲或定時的執行任務
ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1,
new BasicThreadFactory.Builder().namingPattern("test-one-%d").daemon(true).build());
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("線程開始");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程執行完畢");
}
},1, 2, TimeUnit.SECONDS);
}
```
- 寫在前面的話
- Java
- 基礎
- Double的比較
- 小數怎么用二進制表示
- 多線程
- 并發和并行
- 線程池
- 線程池背景
- 線程池構造
- 任務阻塞隊列
- Flutter
- 基礎知識
- Dart基礎
- Android
- 項目架構
- View
- 非UI線程更新View
- AlarmManager
- 對比postDelaryed和Timer
- Bitmap
- 加載100M的圖片卻不撐爆內存
- Bitmap壓縮
- Bitmap局部解碼
- 計算圖片的內存占用
- Android動畫
- Android動畫類型
- Android動畫原理
- 屬性動畫
- 幀動畫
- 補間動畫
- 使用動畫的注意事項
- Android新特性
- 權限組
- Android23(Marshmallow)-6.0
- Android24(Nougat)-7.0
- Android26(Oreo)-8.0
- Android28(Pie)-9.0
- Android29(Q)-10.0
- AndroidX遷移
- Kotlin
- 關鍵字
- Kotlin操作符
- CoroutineScope
- Flow
- CoroutineException