Блокировка уровня класса с блоком синхронизации, несколько потоков в одном экземпляре

#java #synchronization

Вопрос:

У меня есть следующий код, в котором несколько потоков вызывают один и тот же метод экземпляра, защищенный статическим объектом

 package com.data;

class TestThread {

private final static Object object = new Object();

public void myWaitMethod() {
    synchronized (object) {
        System.out.println("Before a "   Thread.currentThread().getId());
        try {
            object.wait();
        } catch (Exception ignore) {
            System.out.println(Thread.currentThread().getId());
        }
        System.out.println("After a "   Thread.currentThread().getId());
    }
}

public void myNotifyMethod() {
    synchronized (object) {
        System.out.println("Before Notify");
        object.notifyAll();
        System.out.println("After b");
    }
}

public static void main(String[] args) throws InterruptedException {
    TestThread aa1 = new TestThread();
    new Thread(() -> aa1.myWaitMethod()).start();
    new Thread(() -> aa1.myWaitMethod()).start();
    Thread.sleep(1000);
    System.out.println("sleep");
    Thread.sleep(1000);
    aa1.myNotifyMethod();
}
}
 

o/p:

 Before a 12
Before a 13
sleep
Before Notify
After b
After a 13
After a 12
 

Я не понимаю, почему «До» дважды печатается, даже если блок синхронизирован.

Ответ №1:

Первая нить получает блокировку, печатает Before A , вторая нить теперь заблокирована. Затем первый поток вызывает wait (после вызова wait поток теряет контроль над блокировкой и переходит в состояние ожидания), второй поток получает блокировку, печатает Before A , а второй поток вызывает wait. (Оба потока находятся в Waiting состоянии,). Затем основной поток получает блокировку, затем уведомляет об этом для обоих потоков.

На диаграмме, показанной ниже, представлены различные состояния потока в любой момент времени.

введите описание изображения здесь

Комментарии:

1. Спасибо, я скучаю по документации об ожидании.