Синхронизация с помощью Wait/Notify
Last updated: 6 мая 2025 г.wait/notify
– используется если нам нужно приостановить один поток и чтобы он ждал пока другой поток даст разрешение на продолжение выполнения остановленного потока.
То есть чтобы один поток дождался формирования какой-либо информации в другом потоке чтобы потом ее использовать
Пример программы:
1class DemoClass {
2 synchronized void part1()
3 {
4 System.out.println("Thread t1 started");
5 //с помощью notify даем разрешение на
6 //продолжение работы потока, который был
7 //остановлен с помощью wait.
8 notify();
9 System.out.println(
10 "Thread t2 now is not locked by wait method anymore");
11 for(int i=0;i<15;i++)
12 {
13 System.out.println("Thread t1 is working now...");
14 }
15 System.out.println("Thread t1 finished his work.");
16 }
17 //wait/notify - вызываются в блоках synchronized
18 //над одним и тем же объектом в данном случае
19 //над объектом DemoClass
20 synchronized void part2()
21 {
22 try {
23 System.out.println("Thread t2 started");
24 System.out.println("Thread t2 waiting");
25 //с помощью wait останавливаем поток, который
26 //зашел в этом synchronized метод и теперь
27 //другие потоки могут заходить в другие
28 //synchronized методы для того чтобы в них
29 //с помощью notify дать разрешение на
30 //продолжение работы потока, который
31 //был заблокирован здесь с помощью wait.
32 wait();
33 System.out.println(
34 "Thread t2 running again");
35 }
36 catch (Exception e) {
37 System.out.println(e.getClass());
38 }
39 System.out.println("Thread t2 finished his work.");
40 }
41}
42
43public class WaitNotifyExample {
44 public static void main(String[] args)
45 {
46 DemoClass obj = new DemoClass();
47 //реализуем run с помощью анонимного класса.
48 //чтобы не создавать два полноценных класса
49 Thread t1 = new Thread(new Runnable() {
50 public void run() { obj.part1(); }
51 });
52 Thread t2 = new Thread(new Runnable() {
53 public void run() { obj.part2(); }
54 });
55 t2.start();
56 try {
57 Thread.sleep(100);
58 }
59 catch(InterruptedException e){}
60 t1.start();
61 }
62}
Вывод:

Программа выполняется в следующей последовательности:
- Запускается t2
- t2 заходит в synchronized метод
- все остальные synchronized методы в obj блокируются и запущенный t1 после t2 не сможет зайти в synchronized блок в obj пока t2 не освободит synchronized блок в obj в который он зашел или пока не дойдет до метода wait
- t2 доходит до wait метода в synchronized, который приостанавливает поток t2
- t1 теперь может зайти в synchronized блок в obj в который он хотел зайти
- notify уведомляет t2 о том, что он может продолжать работу после завершения работы synchronized метода в который сейчас выполняет поток t1
- t1 завершает свою работу
- t2 продолжает работу.
Следующие уроки
Метод yield в Java
10
мин.
Semaphore в Java
10
мин.
ReentrantLock - гибкая альтернатива synchronized
11
мин.