Java 5 引入 Executor 框架,將「任務提交」與「執行策略」解耦。核心介面三層:Executor (最基礎) → ExecutorService (生命週期管理) → ScheduledExecutorService (定時/周期執行)。統一由 Executors 工廠建立各類線程池。
三大介面職責
| 介面 | 核心方法 | 用途 |
Executor | execute(Runnable) | 純提交,無回傳、無管理 |
ExecutorService | submit(Callable/Runnable) → Future
invokeAll/any、shutdown()、shutdownNow() | 任務管理、結果獲取、優雅關閉 |
ScheduledExecutorService | schedule(task, delay, unit)
scheduleAtFixedRate/WithFixedDelay | 定時一次、固定頻率、固定延遲周期執行 |
Executors 工廠常用線程池
| 方法 | 特性 | 適用場景 | ⚠️ 風險 |
newFixedThreadPool(n) | 核心=最大=n,無界隊列 | 長期穩定負載、控制併發度 | 隊列堆積導致 OOM |
newCachedThreadPool() | 核心=0,最大=Integer.MAX,60s 回收閒置 | 短生命周期、突發大量任務 | 無限建立線程 → OOM |
newSingleThreadExecutor() | 單線程串行、保證順序 | 需序列化的任務 (如 DB 寫入) | 單點瓶頸 |
newScheduledThreadPool(n) | 支援定時/周期 | 定時清理、心跳、報表生成 | 任務執行超過周期會疊加 |
newSingleThreadScheduledExecutor() | 單線程定時 | 簡單定時任務 | 同上 |
完整整合範例
import java.util.concurrent.*;
public class ExecutorFrameworkDemo {
static class PrintTask implements Runnable {
@Override public void run() {
System.out.println("Task @" + System.currentTimeMillis() + " [" + Thread.currentThread().getName() + "]");
}
}
static class CancelTask implements Callable<String> {
private final Future<?> target;
CancelTask(Future<?> target) { this.target = target; }
@Override public String call() {
target.cancel(true);
return "Cancelled";
}
}
public static void main(String[] args) throws Exception {
// 1. CachedThreadPool : 適應性線程池
ExecutorService cached = Executors.newCachedThreadPool();
Future<?> f1 = cached.submit(new PrintTask());
Future<String> f2 = cached.submit(new CancelTask(f1));
System.out.println("Cached result: " + f2.get());
cached.shutdownNow();
// 2. FixedThreadPool : 固定 2 線程,驗證隊列等待
ExecutorService fixed = Executors.newFixedThreadPool(2);
fixed.submit(new PrintTask()); // 佔用線程 1
fixed.submit(new PrintTask()); // 佔用線程 2
Future<?> f3 = fixed.submit(new PrintTask()); // 進隊列等待
Future<String> f4 = fixed.submit(new CancelTask(f3));
System.out.println("Fixed result: " + f4.get());
fixed.shutdownNow();
// 3. ScheduledThreadPool : 定時 + 取消示範
ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(2);
PrintTask periodic = new PrintTask();
// 立即開始,每 2 秒執行一次
Future<?> periodicFuture = scheduled.scheduleAtFixedRate(periodic, 0, 2, TimeUnit.SECONDS);
// 5 秒後取消周期任務
Future<String> cancelFuture = scheduled.schedule(new CancelTask(periodicFuture), 5, TimeUnit.SECONDS);
System.out.println("Scheduled cancel: " + cancelFuture.get());
scheduled.shutdownNow();
}
}
關鍵行為驗證點
FixedThreadPool:任務超過核心數進入 **無界隊列** 等待,不會拒絕也不會建立新線程。
scheduleAtFixedRate:若任務執行時間 > 周期,下一次執行會**緊接著上一次結束後立即啟動** (不重疊,但會延遲)。
scheduleWithFixedDelay:上一次結束 → 等待 delay → 下一次啟動 (嚴格間隔)。
shutdown():停止接受新任務,執行完現有任務;shutdownNow():嘗試中斷執行中任務,返回未執行任務列表。
生產級線程池自訂 (避免 Executors 缺陷)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
4, 8, // core=4, max=8
60L, TimeUnit.SECONDS, // 閒置存活 60s
new LinkedBlockingQueue<>(1000), // 有界隊列 1000
new ThreadFactoryBuilder().setNameFormat("biz-worker-%d").build(),
new ThreadPoolExecutor.AbortPolicy() // 滿載拋 RejectedExecutionException
);
《阿里巴巴 Java 開發手冊》強制規約
【強制】 線程池不允許使用 Executors 建立,需通過 ThreadPoolExecutor 明確指定參數,避免 FixedThreadPool/SingleThreadPool (OOM 風險:無界隊列) 與 CachedThreadPool (OOM 風險:無限線程)。