Cuando estaba estudiando sobre cierres y barreras cíclicas, se me ocurrieron estas metáforas. cyclicbarriers: Imagine que una empresa tiene una sala de reuniones. Para comenzar la reunión, un cierto número de asistentes a la reunión deben asistir a la reunión (para hacerlo oficial). El siguiente es el código de un asistente a la reunión normal (un empleado)
class MeetingAtendee implements Runnable {
CyclicBarrier myMeetingQuorumBarrier;
public MeetingAtendee(CyclicBarrier myMileStoneBarrier) {
this.myMeetingQuorumBarrier = myMileStoneBarrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " i joined the meeting ...");
myMeetingQuorumBarrier.await();
System.out.println(Thread.currentThread().getName()+" finally meeting stared ...");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
System.out.println("Meeting canceled! every body dance <by chic band!>");
}
}
}
empleado entra en la reunión, espera a que otros vengan a comenzar la reunión. también se sale de él si la reunión se cancela :) entonces tenemos a THE BOSS de cómo a las dosis no les gusta esperar a que aparezcan otros y si pierde a su paciente, cancela la reunión.
class MeetingAtendeeTheBoss implements Runnable {
CyclicBarrier myMeetingQuorumBarrier;
public MeetingAtendeeTheBoss(CyclicBarrier myMileStoneBarrier) {
this.myMeetingQuorumBarrier = myMileStoneBarrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "I am THE BOSS - i joined the meeting ...");
//boss dose not like to wait too much!! he/she waits for 2 seconds and we END the meeting
myMeetingQuorumBarrier.await(1,TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName()+" finally meeting stared ...");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
System.out.println("what WHO canceled The meeting");
} catch (TimeoutException e) {
System.out.println("These employees waste my time!!");
}
}
}
En un día normal, los empleados vienen a satisfacer esperar a que otros a aparecer y si algunos asistentes don `t vienen tienen que esperar indefinidamente! en alguna reunión especial el jefe viene y que no le gusta que esperar (5 personas tienen que empezar a conocer, pero sólo jefe viene y también un empleado entusiasta) por lo que cancela la reunión (enfadado)
CyclicBarrier meetingAtendeeQuorum = new CyclicBarrier(5);
Thread atendeeThread = new Thread(new MeetingAtendee(meetingAtendeeQuorum));
Thread atendeeThreadBoss = new Thread(new MeetingAtendeeTheBoss(meetingAtendeeQuorum));
atendeeThread.start();
atendeeThreadBoss.start();
de salida:.
//Thread-1I am THE BOSS - i joined the meeting ...
// Thread-0 i joined the meeting ...
// These employees waste my time!!
// Meeting canceled! every body dance <by chic band!>
Hay otro escenario en el que otro hilo externo (un terremoto) cancela la reunión (método de restablecimiento de llamada). en este caso, todos los hilos de espera se despiertan con una excepción.
class NaturalDisasters implements Runnable {
CyclicBarrier someStupidMeetingAtendeeQuorum;
public NaturalDisasters(CyclicBarrier someStupidMeetingAtendeeQuorum) {
this.someStupidMeetingAtendeeQuorum = someStupidMeetingAtendeeQuorum;
}
void earthQuakeHappening(){
System.out.println("earth quaking.....");
someStupidMeetingAtendeeQuorum.reset();
}
@Override
public void run() {
earthQuakeHappening();
}
}
código que se ejecuta permite la salida divertida:
// Thread-1I am THE BOSS - i joined the meeting ...
// Thread-0 i joined the meeting ...
// earth quaking.....
// what WHO canceled The meeting
// Meeting canceled! every body dance <by chic band!>
También puede agregar una secretaria a la sala de reuniones, si se lleva a cabo una reunión que va a documentar todas las cosas, pero ella no es parte de la reunión :
class MeetingSecretary implements Runnable {
@Override
public void run() {
System.out.println("preparing meeting documents");
System.out.println("taking notes ...");
}
}
Cierres: si el jefe enojado quiere realizar una exposición para los clientes de la compañía, cada cosa tiene que estar preparado (recursos). proporcionamos una lista de cosas por hacer cada trabajador (subproceso) dosifica su trabajo y verificamos la lista de tareas pendientes (algunos trabajadores pintan, otros preparan el sistema de sonido ...). cuando todos los elementos en la lista de tareas están completos (se proporcionan recursos) podemos abrir las puertas a los clientes.
public class Visitor implements Runnable{
CountDownLatch exhibitonDoorlatch = null;
public Visitor (CountDownLatch latch) {
exhibitonDoorlatch = latch;
}
public void run() {
try {
exhibitonDoorlatch .await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("customer visiting exebition");
}
}
Y los trabajadores cómo se están preparando la exposición:
class Worker implements Runnable {
CountDownLatch myTodoItem = null;
public Worker(CountDownLatch latch) {
this.myTodoItem = latch;
}
public void run() {
System.out.println("doing my part of job ...");
System.out.println("My work is done! remove it from todo list");
myTodoItem.countDown();
}
}
CountDownLatch preperationTodoList = new CountDownLatch(3);
// exhibition preparation workers
Worker electricalWorker = new Worker(preperationTodoList);
Worker paintingWorker = new Worker(preperationTodoList);
// Exhibition Visitors
ExhibitionVisitor exhibitionVisitorA = new ExhibitionVisitor(preperationTodoList);
ExhibitionVisitor exhibitionVisitorB = new ExhibitionVisitor(preperationTodoList);
ExhibitionVisitor exhibitionVisitorC = new ExhibitionVisitor(preperationTodoList);
new Thread(electricalWorker).start();
new Thread(paintingWorker).start();
new Thread(exhibitionVisitorA).start();
new Thread(exhibitionVisitorB).start();
new Thread(exhibitionVisitorC).start();
Cierres son para la espera de los acontecimientos; las barreras son para esperar otros hilos. - Java Concurrency in Practice, B.Goetz et al. – user2418306