Получает ли поток, получающий блокировку монитора объекта, также объектную блокировку суперкласса? - PullRequest
0 голосов
/ 29 сентября 2018

Когда поток получает блокировку монитора объекта (скажем, класса 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) {}
    }
}

Почему это внутреннее несоответствие в поведении блокировки монитора объектов для суперкласса по сравнению с любым другим классом?

Насколько я понимаю в отношении блокировки монитора объектовничего не хватает?

1 Ответ

0 голосов
/ 30 сентября 2018

Я не совсем уверен, имеет ли ваш вопрос какой-либо смысл.Экземпляра «суперкласса» не существует, поскольку экземпляр подкласса совпадает с экземпляром его суперкласса, в противном случае вы будете создавать экземпляры нескольких объектов каждый раз, когда используете ключевое слово new.Это также причина, почему вы не можете сделать что-то вроде:

synchronized (super) {
}

В конечном счете, способность использовать wait и notify[All] принадлежит Object (поскольку они являются окончательными методами), чтоэто супер-супер класс каждого класса.Вы можете думать о синхронизации на this как о синхронизации на мониторе, принадлежащем Object, поскольку внутренние блокировки связаны с объектами, а не с классами (важное отличие состоит в том, что может быть получена внутренняя блокировка, связанная с объектом Class).

Следовательно, поскольку A и B являются одним и тем же экземпляром Object, не имеет значения, что вы синхронизировались в B и вызываете wait из Aони оба ссылаются на один и тот же Object.

...