public static class Test1Thread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Test1," + Thread.currentThread().getName() + ", i = " + i);
}
}
}
// 啟動:new Test1Thread().start();
public static class Test2Thread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Test2," + Thread.currentThread().getName() + ", i = " + i);
}
}
}
// 啟動:new Thread(new Test2Thread()).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Test3," + Thread.currentThread().getName() + ", i = " + i);
}
}
}).start();
關鍵: 必須呼叫 start() 而非 run(),才會開啟新執行緒。
count++private static int count = 0; // 非線程安全
| 方案 | 核心類/關鍵字 | 原理 | 效能 | 適用場景 |
|---|---|---|---|---|
| 無同步 | — | — | 最高 | 單執行緒、只讀 |
| 互斥鎖 | synchronized | 監視器鎖,阻塞同步 | 中 | 臨界區邏輯複雜 |
| CAS 原子類 | AtomicInteger | Compare-And-Swap,非阻塞 | 高 | 簡單計數、累加器 |
| volatile | volatile | 可見性保證,非原子性 | 最高 | 狀態旗標、單次寫入 |
// 1. 不安全
private static int count = 0;
// 2. synchronized
private static final Object lock = new Object();
synchronized(lock) { count++; }
// 3. AtomicInteger (CAS)
private static AtomicInteger ai = new AtomicInteger();
ai.incrementAndGet();
// 4. volatile (錯誤示範:++ 非原子)
private static volatile int countV = 0;
countV++; // 仍不安全!
public int put() { carList.add(car); carNums++; return carNums; }
public int get() { if (!carList.isEmpty()) { carList.remove(...); carNums--; } return carNums; }
// 問題:race condition、資料不一致
public synchronized int put() { ... }
public synchronized int get() { ... }
// 優點:簡單;缺點:粒度粗,吞吐受限
private Object lock = new Object();
public int put() {
synchronized (lock) {
while (carList.size() == MAX) lock.wait(); // 滿了等待
carList.add(car); carNums++;
lock.notify(); // 喚醒消費者
return carNums;
}
}
public int get() {
synchronized (lock) {
while (carList.isEmpty()) lock.wait(); // 空了等待
carList.remove(...); carNums--;
lock.notify(); // 喚醒生產者
return carNums;
}
}
關鍵點:
while 而非 if 檢查條件(防止虛假喚醒)notify() 喚醒單一執行緒,notifyAll() 喚醒全部lock)新建 → 就緒 → 執行 → 阻塞(wait/sleep/IO) → 死亡
BlockingQueue(ArrayBlockingQueue、LinkedBlockingQueue)替代手寫 wait/notifyLongAdder(Java 8+)優於 AtomicLong