class Task implements Runnable {
private static int idGen = 0;
private final int id = idGen++;
private int countDown = 5;
private int priority;
public void setPriority(int p) { priority = p; }
@Override public void run() {
Thread.currentThread().setPriority(priority);
while (countDown-- > 0) {
// 模擬計算負載
double d = 1.2;
while (d < 10000) d += (Math.E + Math.PI) / d;
System.out.println("#" + id + "(" + countDown + ") priority=" + priority);
}
}
}
public class BasicThread {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Task t = new Task();
t.setPriority(i == 0 ? Thread.MAX_PRIORITY : Thread.MIN_PRIORITY);
new Thread(t).start();
}
}
}
觀察:高優先級線程 (id=0) 可能搶佔更多 CPU 時間片,但**優先級只是提示,不保證調度順序**,受 OS、JVM 實現影響。
手動管理 new Thread() 缺點:頻繁創建銷毀開銷大、無法控制併發數、異常處理困難、無返回值。ExecutorService 解決所有問題。
import java.util.concurrent.*;
public class ExecutorDemo {
public static void main(String[] args) {
// 1. 固定線程池 (適合長任務)
ExecutorService fixed = Executors.newFixedThreadPool(4);
// 2. 緩存線程池 (適合大量短任務)
ExecutorService cached = Executors.newCachedThreadPool();
// 3. 單線程池 (串行執行)
ExecutorService single = Executors.newSingleThreadExecutor();
// 4. 定時任務池
ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(2);
// 提交任務
for (int i = 0; i < 10; i++) {
Task t = new Task();
t.setPriority(i == 0 ? Thread.MAX_PRIORITY : Thread.NORM_PRIORITY);
cached.execute(t); // 無返回值
// Future> f = cached.submit(t); // 有返回值/可取消
}
// 關閉流程
cached.shutdown(); // 拒絕新任務,處理完現有任務
try {
if (!cached.awaitTermination(60, TimeUnit.SECONDS)) {
cached.shutdownNow(); // 強制中斷
}
} catch (InterruptedException e) {
cached.shutdownNow();
}
}
}
| 接口 | 說明 |
|---|---|
| Executor | 最頂層,只有一個 execute(Runnable) |
| ExecutorService | 擴展生命周期管理 (shutdown, submit, invokeAll...) |
| ScheduledExecutorService | 擴展定時/周期執行 |
| ThreadPoolExecutor | 核心實現,可自定義核心/最大線程、隊列、拒絕策略、線程工廠 |
ThreadPoolExecutor pool = new ThreadPoolExecutor(
4, // corePoolSize
8, // maximumPoolSize
60L, TimeUnit.SECONDS,// keepAliveTime
new LinkedBlockingQueue<>(100), // workQueue 有界隊列防 OOM
new ThreadFactoryBuilder().setNameFormat("biz-%d").build(), // 命名便於排查
new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略:由調用線程執行,緩衝峰值
);
LinkedBlockingQueue,防止任務堆積 OOM。ThreadFactoryBuilder (Guava) 或自定義工廠,日誌排查神器。CallerRunsPolicy 適合不想丟任務且能接受延遲的場景。併發編程核心:**線程池隔離、有界資源、可觀測性**。