本文基於《Thinking in Java》並發章節,系統整理線程基礎 API、Executor 框架、Callable/Future、線程優先級、Join 機制,以及共享資源同步的核心手段。
run(),每個實例獨擁任務邏輯,單繼承限制。
class LiftOff implements Runnable {
int countDown = 10;
public void run() {
while (countDown-- > 0) {
System.out.print("#" + id + "(" + (countDown > 0 ? countDown : "LiftOff!") + "), ");
Thread.yield(); // 禮讓 CPU,促進併發測試
}
}
}
new Thread(new LiftOff()).start(); // 必須調用 start(),而非 run()
start() 完成線程初始化並調用 run();直接調用 run() 只是普通方法調用,無新線程。
JDK 5+ 推薦使用 ExecutorService 替代手動 new Thread。
| 工廠方法 | 特點 | 適用場景 |
|---|---|---|
newCachedThreadPool() | 無界,按需創建,60s 回收空閒 | 大量短任務 |
newFixedThreadPool(n) | 固定 n 線程,隊列無界 | 長期運行、控制並發度 |
newSingleThreadExecutor() | 單線程串行,保證順序 | 順序處理、避免併發衝突 |
newScheduledThreadPool(n) | 定時/周期執行 | 定時任務 |
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) exec.execute(new LiftOff());
exec.shutdown(); // 拒絕新任務,等待已提交任務完成
Runnable 無返回值;Callable<V> 返回 V 並可拋異常。submit(Callable) 返回 Future<V>,get() 阻塞獲取結果。
class TaskWithResult implements Callable<String> {
int id;
public String call() { return "result of " + id; }
}
ExecutorService exec = Executors.newCachedThreadPool();
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) futures.add(exec.submit(new TaskWithResult(i)));
for (Future<String> f : futures) System.out.println(f.get()); // 阻塞等待結果
exec.shutdown();
MIN_PRIORITY=1 ~ NORM_PRIORITY=5 ~ MAX_PRIORITY=10。thread.setPriority(Thread.MAX_PRIORITY)。
class SimplePriorities implements Runnable {
int priority;
public void run() {
Thread.currentThread().setPriority(priority);
while (true) { /* 密集計算 */ Thread.yield(); }
}
}
exec.execute(new SimplePriorities(Thread.MAX_PRIORITY)); // 高優先級搶佔更多 CPU
t.join():當前線程阻塞,直到 t 結束。t.join(millis):帶超時等待。InterruptedException。
class Sleeper extends Thread { /* sleep 固定時間 */ }
class Joiner extends Thread {
Sleeper s;
public void run() {
try { s.join(); } catch (InterruptedException e) { ... }
System.out.println(getName() + " join completed");
}
}
Sleeper s = new Sleeper("S", 1500);
new Joiner("J", s).start();
s.interrupt(); // 中斷睡眠,Joiner 捕獲異常繼續
多線程並發修改共享變量導致競態條件:
class Counter implements Runnable {
static int counter = 0;
public void run() { for (int i=0; i<1_000_000; i++) counter++; }
}
// 10 線程並發,結果遠小於 10_000_000
Java 提供三大同步手段:
| 機制 | 關鍵字/類 | 特點 |
|---|---|---|
| 內置鎖 | synchronized 方法/塊 | 隱式鎖,JVM 優化極佳(偏向鎖、輕量級鎖、鎖消除) |
| 顯式鎖 | Lock / ReentrantLock | 手動 lock/unlock,支持中斷、超時、多 Condition、公平性 |
| 原子變量 | AtomicInteger 等 | CAS 無鎖,適合簡單計數器 |