Когда я изучал защелки и циклические барьеры, я придумал эту метафору.
Циклические барьеры . Представьте, что в компании есть комната для переговоров. Чтобы начать собрание, на собрание должно прийти определенное количество участников (чтобы сделать его официальным). ниже приведен код обычного участника собрания (сотрудника)
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!>");
}
}
}
сотрудник присоединяется к собранию, ждет, пока другие придут, чтобы начать собрание. кроме того, он выходит, если собрание отменяется :) тогда у нас есть БОСС, как дозы не любят ждать появления других, и если он теряет своего пациента, он отменяет собрание.
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!!");
}
}
}
В обычный день сотрудник приходит на собрание, ожидая появления других, и если некоторые посетители не приходят, им приходится ждать бесконечно! на каком-то специальном собрании приходит начальник, и он не любит ждать. (5 человек должны начать совещание, но приходит только начальник, а также служащий с энтузиазмом), поэтому он отменяет собрание (сердито)
CyclicBarrier meetingAtendeeQuorum = new CyclicBarrier(5);
Thread atendeeThread = new Thread(new MeetingAtendee(meetingAtendeeQuorum));
Thread atendeeThreadBoss = new Thread(new MeetingAtendeeTheBoss(meetingAtendeeQuorum));
atendeeThread.start();
atendeeThreadBoss.start();
Вывод:
//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!>
Существует еще один сценарий, в котором другой внешний поток (землетрясение) отменяет собрание (метод сброса вызова). в этом случае все ожидающие потоки просыпаются в результате исключения.
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();
}
}
выполнение кода приведет к забавному выводу:
// 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!>
Вы также можете добавить секретаря в комнату для собраний, если она проводится, она регистрирует все, но не участвует в собрании:
class MeetingSecretary implements Runnable {
@Override
public void run() {
System.out.println("preparing meeting documents");
System.out.println("taking notes ...");
}
}
Защелки : если злой начальник хочет провести выставку для клиентов компании, все должно быть готово (ресурсы). мы предоставляем список дел каждому рабочему (Thread), дозирующему его работу, и мы проверяем список дел (некоторые рабочие рисуют, другие готовят звуковую систему ...). Когда все пункты в списке дел завершены (ресурсы предоставлены), мы можем открыть двери для клиентов.
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");
}
}
А рабочие как готовят выставку
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();