Синхронизация с помощью 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(); } }

Вывод:

Example

Программа выполняется в следующей последовательности:

  1. Запускается t2
  2. t2 заходит в synchronized метод
  3. все остальные synchronized методы в obj блокируются и запущенный t1 после t2 не сможет зайти в synchronized блок в obj пока t2 не освободит synchronized блок в obj в который он зашел или пока не дойдет до метода wait
  4. t2 доходит до wait метода в synchronized, который приостанавливает поток t2
  5. t1 теперь может зайти в synchronized блок в obj в который он хотел зайти
  6. notify уведомляет t2 о том, что он может продолжать работу после завершения работы synchronized метода в который сейчас выполняет поток t1
  7. t1 завершает свою работу
  8. t2 продолжает работу.

Метод yield в Java

Метод yield() в Java: зачем поток уступает свое время другим? Разбор работы планировщика потоков и практическое применение с примером.
Time to read: 10

Semaphore в Java

Semaphore в Java: контроль доступа потоков к ресурсам. Как ограничить число одновременных операций и управлять очередью. Рабочий пример с кодом.
Time to read: 10

ReentrantLock - гибкая альтернатива synchronized

ReentrantLock в Java: мощная альтернатива synchronized с гибкой блокировкой любых участков кода. Примеры, отличия и преимущества для многопоточности.
Time to read: 11