private static String lock = "";
synchronized(lock) {
lock = "changed"; // 關鍵錯誤!
while (true); // 無限迴圈
}
兩執行緒分別呼叫兩個同步方法,理應只有一個進入無限迴圈,但實際輸出:
method1
staticMethod1
說明兩執行緒同時進入了同步區塊,同步失效。
String s = "hello";
System.out.println(s.hashCode()); // 123
s = "world";
System.out.println(s.hashCode()); // 456 // hashCode 改變 = 新物件
synchronized(lock),鎖住「舊字串物件」。lock = "changed",lock 參考指向「新字串物件」。synchronized(lock),鎖住的是「新字串物件」,與 A 鎖不同,不互斥。
private final static String LOCK = ""; // 編譯期保證不被重新賦值
// 或
private final static Object LOCK = new Object(); // 推薦:專用不可變物件
final 保證參考不變,鎖物件恆為同一個。new Object() 或 new byte[0] 作為純鎖物件,語意清晰。本質相同:監視器鎖的互斥性。
synchronized 參數必須是物件參考,基本型別(int、boolean 等)無法直接同步。ConcurrentHashMap 等進階結構。