在 Java 多線程編程中,synchronized(new Object()){} 和 Object obj = new Object(); synchronized(obj){} 這兩種寫法看似相似,實則行為截然不同。前者會導致多線程並行執行,後者則實現線程串行。這究竟是什麼原因?
class Card implements Runnable {
private static int cards = 100;
Object obj = new Object();
public void run() {
while (true) {
synchronized(obj) { // 若改為 synchronized(new Object()) 則失去同步效果
if (cards > 0) {
try { Thread.sleep(10); } catch (Exception e) {}
System.out.println(Thread.currentThread().getName() + "------" + cards--);
} else {
break;
}
}
}
}
}
每次進入同步塊時,new Object() 都會創建一個全新的鎖對象。四個線程各自持有不同的鎖,自然不存在競爭關係,因此呈現並行執行狀態。這實際上失去了同步互斥的意義。
obj 作為類的成員變量,在對象創建時初始化一次。所有線程共享同一個 Card 實例(示例中 `new Card()` 僅創建一次),因此共用同一把鎖。線程間產生競爭,被迫串行執行,達到線程安全目的。
理解這一點,是掌握 Java 並發編程基石的關鍵一步。