オブジェクトにいくつかのsynchronized
ブロックがある場合 (たとえば) 、Java はこれらすべてのs が同じか異なるかobj
をどのようにチェックしますか?obj
例えば:
public static f() {
synchronized ("xyz") {
...
}
}
上記の関数f
が2つのスレッドによって同時に呼び出された場合、それらは他のスレッドをブロックしますか? 各スレッドが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
バージョンが機能していたので、 Java がブロックのチェックをStr
使用するか、またはおそらく使用することを期待していましたが、2 番目のテストからはそうではないようです。equals
synchronized
hashCode
String
特殊なケースですか?