public static int count = 5; // 共享變數
public void run() {
for (int i=0; i<=4; i++) {
Thread.sleep(1000);
if (count > 0) {
System.out.println(Thread.currentThread().getName() + ",count= " + this.count--);
}
}
}
count > 0 檢查與 count-- **非原子操作**,三個執行緒可能同時通過判斷,導致**超賣**(輸出出現重複數字、負數)。int 非 volatile,甚至可能發生**可見性問題**(執行緒讀到舊值)。private static final Object lock = new Object();
// 或直接 synchronized(this) 但 this 可能不同實例,靜態變數鎖類對象更好
synchronized (Ticket.class) {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + ",count= " + count--);
}
}
private static final AtomicInteger count = new AtomicInteger(5);
public void run() {
for (int i=0; i<5; i++) {
Thread.sleep(1000);
int current = count.decrementAndGet(); // 原子遞減並取新值
if (current >= 0) {
System.out.println(Thread.currentThread().getName() + ",count= " + current);
}
}
}
修正後:**無重複、無負數、總數精確為 5**,三個執行緒輪流賣完 5 張票。