ラッチとサイクリックバリアについて研究していたとき、この比喩を思いつきました。
循環障壁:会社に会議室があると想像してください。会議を開始するには、会議の参加者の一定数が会議に参加する必要があります(正式にするため)。以下は、通常の会議出席者(従業員)のコードです。
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 ...");
}
}
ラッチ:怒っている上司が企業顧客向けに展示会を開催したい場合、すべてのものを準備する必要があります(リソース)。私たちは、すべての作業者(スレッド)が彼の仕事を投入するためのto-doリストを提供し、to-doリストをチェックします(一部の作業者は塗装を行い、他の作業者はサウンドシステムを準備します...)。to-doリストのすべての項目が完了すると(リソースが提供されます)、お客様への扉を開くことができます。
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();