Когда поток получает блокировку монитора объекта (скажем, класса B), он получает блокировку монитора объекта, принадлежащего своему суперклассу (скажем, класс A, где B расширяет A)?
Observation # 1 - Когда поток (которому принадлежит блокировка монитора производного объекта B через синхронизированный метод) вызывает wait () внутри суперкласса A, второй поток получает блокировку монитора объекта B и переходит к ожиданию в A.Наконец, оба потока одновременно выходят из монитора объектов B.
Насколько я понимаю, поток должен вызывать wait()
для объекта, чьей блокировкой он владеет, иначе это приведет к исключению IllegalMonitorStateException.Причина, по которой исключение не вызывается, когда wait () вызывается внутри метода экземпляра A, означает ли это, что поток, владеющий блокировкой объекта B, также владеет блокировкой объекта A, это суперкласс?
Проверено статей насинхронизация и встроенные блокировки - Что собственно означает встроенная блокировка для класса Java? https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
public class Obs2 {
public static void main(String[] args) {
A a = new B();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start(); t2.start();
}
}
class A implements Runnable {
public void run() {
try {
wait(2000); // OK; No IllegalMonitorStateException
} catch (InterruptedException e) {}
}
}
class B extends A {
@Override
public synchronized void run() {
super.run();
}
}
Observation # 2 - Когда поток(который владеет блокировкой монитора объекта A через синхронизированный метод) вызывает wait () внутри любого произвольного класса C, он вызывает исключение IllegalMonitorStateException.
Это предполагает, что поток вызывает wait () для объекта C, в то время как он владеет блокировкой для объекта A, которая отличается.Отсюда и исключение.
public class Obs2 {
public static void main(String[] args) {
A a = new A();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start(); t2.start();
}
}
class A implements Runnable {
public synchronized void run() {
(new C()).display(this);
}
}
class C {
public void display() {
try {
wait(2000); //--> will lead to IllegalMonitorStateException
} catch (InterruptedException e) {}
}
}
Почему это внутреннее несоответствие в поведении блокировки монитора объектов для суперкласса по сравнению с любым другим классом?
Насколько я понимаю в отношении блокировки монитора объектовничего не хватает?