Самый простой способ понять, удастся он или нет - просто запустить его.Я переписал ваш код в рабочий пример, и в обоих случаях он действительно выводит «Hello».
public class XYZ {
public void someFunction() {
synchronized (this) {
System.out.println("Hello");
}
}
}
public class SomeClass {
private XYZ xyz = new XYZ();
public void functionCalled() {
synchronized (this) {
xyz.someFunction();
}
}
public static void main(String[] args) {
new SomeClass().functionCalled();
}
}
Я также переписал ваши методы для использования блоков синхронизации.Они работают так, что никакие потоки не могут войти в блок, если внутри него находится другой поток, и объект (блокировка) одинаков.Здесь вы можете видеть, что обе функции синхронизируются по this
, что относится к двум разным объектам, поскольку эти два метода принадлежат двум разным классам.Здесь нет конфликта.
functionCalled
синхронизируется по экземпляру SomeClass
someFunction
синхронизируется по экземпляру XYZ
Это отличается от примерав твоей книге я думаю, что смысл примера в том, что на самом деле замки одинаковы!В некоторых средах это может вызвать взаимоблокировку, но, как указано, не в Java.Возьмите этот пример.
public class XYZ {
public void someFunction() {
synchronized (this) {
System.out.println("Hello");
}
}
}
public class SomeClass {
private XYZ xyz = new XYZ();
public void functionCalled() {
synchronized (xyz) {
xyz.someFunction();
}
}
public static void main(String[] args) {
new SomeClass().functionCalled();
}
}
Может выглядеть похоже, но в этом случае functionCalled
синхронизируется по тому же объекту, иначе.они используют тот же объект, что и замок!Дело в том, что текущий поток уже имеет блокировку на объекте, поскольку блокировки основаны на отдельных потоках, поэтому он может безопасно войти в синхронизированный блок и не пытается снова получить блокировку.Если бы он получал блокировку для каждого вызова, он попытался бы снова получить блокировку и застрял, так как первый вызов уже владеет блокировкой.