Kiedy masz kilka bloków synchronized
na obiekcie (powiedzmy) obj
, to w jaki sposób Java sprawdza, czy wszystkie te obj
s są takie same lub różne?Blokady Java: w jaki sposób sprawdzanie równości dla blokad monitora odbywa się w bloku synchronicznym?
Na przykład:
public static f() {
synchronized ("xyz") {
...
}
}
Jeżeli powyższa funkcja f
nazywa się jednocześnie dwa wątki będą blokować drugiego? Zauważ, że każdy wątek otrzyma nowe wystąpienie obiektu String
.
Aby to sprawdzić, napisałem poniższy kod testowy i rzeczywiście wygląda na to, że powyższy blok zadziała, ale są też inne nieoczekiwane rezultaty.
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;
}
}
}
Po uruchomieniu powyższego kodu woli pojawić się następujący komunikat: -
f1: A
f1: A DONE
f1: B
f1: B DONE
Jednak gdybym skomentować f1("A", "Str");
i f1("B", "Str");
linie i odkomentuj linie nad nimi, a następnie wynik jest : -
f1: A
f1: B
f1: A DONE
f1: B DONE
Ponieważ wersja Str
pracował więc spodziewałem się, że być może Java używa equals
che ck dla synchronized
bloku lub może hashCode
, ale z drugiego testu wydaje się, że tak nie jest w ogóle.
Czy String
jest specjalny przypadek?