Бесплатный курс по Java: от основ до продвинутого уровня
Синхронизация с помощью Wait/Notify в Java
wait/notify – используется если нам нужно приостановить один поток и чтобы он ждал пока другой поток даст разрешение на продолжение выполнения остановленного потока.
То есть чтобы один поток дождался формирования какой-либо информации в другом потоке чтобы потом ее использовать
Пример программы:
class DemoClass {
synchronized void part1()
{
System.out.println(“Thread t1 started”);
//с помощью notify даем разрешение на
//продолжение работы потока, который был
//остановлен с помощью wait.
notify();
System.out.println(
“Thread t2 now is not locked by wait method anymore”);
for(int i=0;i<15;i++)
{
System.out.println("Thread t1 is working now...");
}
System.out.println("Thread t1 finished his work.");
}
//wait/notify - вызываются в блоках synchronized
//над одним и тем же объектом в данном случае
//над объектом DemoClass
synchronized void part2()
{
try {
System.out.println("Thread t2 started");
System.out.println("Thread t2 waiting");
//с помощью wait останавливаем поток, который
//зашел в этом synchronized метод и теперь
//другие потоки могут заходить в другие
//synchronized методы для того чтобы в них
//с помощью notify дать разрешение на
//продолжение работы потока, который
//был заблокирован здесь с помощью wait.
wait();
System.out.println(
"Thread t2 running again");
}
catch (Exception e) {
System.out.println(e.getClass());
}
System.out.println("Thread t2 finished his work.");
}
}
public class WaitNotifyExample {
public static void main(String[] args)
{
DemoClass obj = new DemoClass();
//реализуем run с помощью анонимного класса.
//чтобы не создавать два полноценных класса
Thread t1 = new Thread(new Runnable() {
public void run() { obj.part1(); }
});
Thread t2 = new Thread(new Runnable() {
public void run() { obj.part2(); }
});
t2.start();
try {
Thread.sleep(100);
}
catch(InterruptedException e){}
t1.start();
}
}
Вывод:
Программа выполняется в следующей последовательности:
Запускается t2
t2 заходит в synchronized метод
все остальные synchronized методы в obj блокируются и запущенный t1 после t2 не сможет зайти в synchronized блок в obj пока t2 не освободит synchronized блок в obj в который он зашел или пока не дойдет до метода wait
t2 доходит до wait метода в synchronized, который приостанавливает поток t2
t1 теперь может зайти в synchronized блок в obj в который он хотел зайти
notify уведомляет t2 о том, что он может продолжать работу после завершения работы synchronized метода в который сейчас выполняет поток t1