Lorsque j'étudiais sur les verrous et les barrières cycliques, j'ai trouvé ces métaphores.
cyclicbarriers : Imaginez qu'une entreprise dispose d'une salle de réunion. Pour démarrer la réunion, un certain nombre de participants doivent venir à la réunion (pour la rendre officielle). ce qui suit est le code d'un participant normal à une réunion (un employé)
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!>");
}
}
}
l'employé se joint à la réunion, attend que d'autres viennent pour commencer la réunion. aussi il est sorti si la réunion est annulée :) alors nous avons THE BOSS comment les doses n'aiment pas attendre que les autres se présentent et s'il perd son patient, il annule la réunion.
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!!");
}
}
}
Un jour normal, les employés viennent à la réunion en attendant que d'autres se présentent et si certains participants ne viennent pas, ils doivent attendre indéfiniment! dans une réunion spéciale, le patron vient et il n'aime pas attendre. (5 personnes doivent commencer à se rencontrer mais seul le patron vient et aussi un employé enthousiaste) alors il annule la réunion (avec colère)
CyclicBarrier meetingAtendeeQuorum = new CyclicBarrier(5);
Thread atendeeThread = new Thread(new MeetingAtendee(meetingAtendeeQuorum));
Thread atendeeThreadBoss = new Thread(new MeetingAtendeeTheBoss(meetingAtendeeQuorum));
atendeeThread.start();
atendeeThreadBoss.start();
Production:
//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!>
Il existe un autre scénario dans lequel un autre thread extérieur (un tremblement de terre) annule la réunion (méthode de réinitialisation des appels). dans ce cas, tous les threads en attente sont réveillés par une exception.
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();
}
}
l'exécution de code entraînera une sortie amusante:
// 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!>
Vous pouvez également ajouter une secrétaire à la salle de réunion, si une réunion a lieu, elle documentera tout mais elle ne fait pas partie de la réunion:
class MeetingSecretary implements Runnable {
@Override
public void run() {
System.out.println("preparing meeting documents");
System.out.println("taking notes ...");
}
}
Loquets : si le patron en colère veut organiser une exposition pour les clients de l'entreprise, tout doit être prêt (ressources). nous fournissons une liste de tâches à chaque travailleur (Thread) dose son travail et nous vérifions la liste de tâches (certains travailleurs font de la peinture, d'autres préparent un système de sonorisation ...). lorsque tous les éléments de la liste de tâches sont terminés (les ressources sont fournies), nous pouvons ouvrir les portes aux clients.
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");
}
}
Et les ouvriers comment préparent l'exposition:
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();