Сводка для механизма ожидания / уведомления:
1) текущий поток достигает блока синхронизированного кода одного объекта, который содержит вызов wait () , он конкурирует с другими потоками за блокировку (монитор объекта), как победитель, он выполняет блок до тех пор, пока вызовы wait ().
2) вызывая wait (), текущий поток снимает блокировку с другими конкурирующими потоками, затем останавливает выполнение, ожидает отправки уведомления от другого потока, которому удается получить блокировку.
JavaDoc:
Тема становится владельцем
монитор объекта в одном из трех
способы:
• Выполнение синхронизированного экземпляра
метод этого объекта.
• Выполнив
тело синхронизированного оператора
который синхронизируется на объекте.
• Для
объекты типа Class, выполняя
синхронизированный статический метод этого
класс.
3) другой поток достигает еще одного синхронизированного блока кода того же объекта, который содержит вызов notify / notifyAll (), конкурирует с другими потоками за блокировку, как победитель, он выполняет блок до завершения вызов для уведомления / notifyAll (). Он снимет блокировку либо по вызову wait (), либо по окончании выполнения в блоке.
4) после получения notify / notifyAll () текущий поток конкурирует за блокировку, а в качестве победителя выполнение продолжается там, где оно остановлено.
простой пример:
public class Main3 {
public static void main(String[] args) {
Test3 t = new Test3();
new Thread(t).start();
new Thread(t).start();
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
t.testNotifyAll();
}
}
class Test3 implements Runnable {
synchronized public void run() {
System.out.println(Thread.currentThread().getName() + ": " + "wait block got the lock");
try {
wait();
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "wait block got the lock again");
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "bye wait block");
}
synchronized void testNotifyAll() {
System.out.println(Thread.currentThread().getName() + ": " + "notify block got the lock");
notifyAll();
System.out.println(Thread.currentThread().getName() + ": " + "notify sent");
try {
Thread.sleep(2000);
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "bye notify block");
}
}
выход:
Thread-0 (или 1): блок ожидания получил
замок
Thread-1 (или 0): получен блок ожидания
замок
main: блок уведомлений получил
замок
main: уведомление отправлено
основной: пока блок уведомлений
Thread-0 (или 1): блок ожидания
снова получил замок
Тема-0 (или 1): пока
блок ожидания
Thread-1 (или 0): блок ожидания
снова получил замок
Тема-1 (или 0): пока
блок ожидания