package ar.com.javacuriosities.threads; public class Lesson11WaitAndNotify { public static void main(String[] args) { try { /* * Creamos el objeto meeting que se usar como shared lock y usar los métodos wait() y notifyAll() */ Meeting meeting = new Meeting(); /* * Creamos los objetos que comparten la reunion */ Employee worker01 = new Employee("Homero Simpson", meeting); Employee worker02 = new Employee("Pablo Marmol", meeting); Employee worker03 = new Employee("Don Quijote", meeting); Boss boss = new Boss("Cosme Fulanito", meeting); // Start employees worker01.start(); worker02.start(); worker03.start(); /* * Esperamos para evitar deadlocks, si descomentamos esta línea en * algunos casos se podría generar un deadlock porque el jefe llega * antes y notifica a todos pero no todos están esperando. * * Para resolver esto podríamos usar un wait con tiempo dentro de un ciclo que verifique si ya llego el jefe o no * Homework :) */ Thread.sleep(2000); // Start boss boss.start(); } catch (InterruptedException e) { // Log and Handle exception e.printStackTrace(); } } /* * Esta clase representa la encargada de avisar si debe saludar o esperar */ private static final class Meeting { public Meeting() { } /* * Los empleados van a quedar esperando a que llegue el jefe * Se hace wait del thread que esta corriendo y se bloquea, es importante marcar que el thread * suelta el lock que obtuvo al entrar al método, siempre que usamos wait() debemos estar en un contexto * sincronizado */ public synchronized void waitBoss(String name) { try { System.out.println(name + " is waiting"); wait(); System.out.println(name + ": Good Morning boss"); } catch (InterruptedException ex) { ex.printStackTrace(); } } /* * Cuando el jefe llega saluda a todos y les informa que llego por medio del notifyAll(), * esto despierta a todos los thread que hicieron wait() antes que el llegue */ public synchronized void startMeeting(String name) { System.out.println(name + " -: Good Morning slaves :)"); // Si cambiamos el notifyAll() por notify() se genera un deadlock, por el notify solo informa a un thread notifyAll(); } } private static final class Employee extends Thread { private Meeting meeting; public Employee(String name, Meeting meeting) { super(name); this.meeting = meeting; } @Override public void run() { System.out.println(getName() + " arrives at the office."); meeting.waitBoss(getName()); } } private static final class Boss extends Thread { private Meeting meeting; public Boss(String name, Meeting meeting) { super(name); this.meeting = meeting; } @Override public void run() { System.out.println(getName() + " arrives at the office."); meeting.startMeeting(getName()); } } }