如果在對象(比如說)obj
上有塊,那麼Java如何檢查這些obj
是否相同或不同?Java鎖定:如何在同步塊中完成監視器鎖定的相等性檢查?
例如:
public static f() {
synchronized ("xyz") {
...
}
}
如果上述功能f
同時由兩個線程它們將阻止另一種叫?注意每個線程都會得到一個新的String
對象實例。
爲了檢查這個,我寫了下面的測試代碼,看起來上面的代碼塊確實可以工作,但是還有其他意想不到的結果。
public class Test {
public static void main(String[] args){
new Thread() {
public void run() {
//f1("A", new X());
f1("A", "Str");
}
}.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//f1("B", new X());
f1("B", "Str");
}
public static void f1(String a, Object x) {
synchronized(x) {
System.out.println("f1: " + a);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("f1: " + a + " DONE");
}
}
private static class X {
public boolean equals(Object o) {
System.out.println("equals called");
return true;
}
public int hashCode() {
System.out.println("hashCode called");
return 0;
}
}
}
如果你運行上面的代碼,你會得到下面的輸出: -
f1: A
f1: A DONE
f1: B
f1: B DONE
但是,如果我評論了f1("A", "Str");
和f1("B", "Str");
線並取消它們上面的線,那麼結果是: -
f1: A
f1: B
f1: A DONE
f1: B DONE
由於Str
版本的工作,所以我期待,也許Java使用equals
車CK爲塊或可能hashCode
,但從第二次測試看來,情況並非如此。
是String
的特例嗎?