CyclicBarrier國內(nèi)有些人翻譯做柵欄臭家。
柵欄(Barrier)類似于閉鎖呵恢,它能阻塞一組線程直到某個事件發(fā)生种蘸。柵欄與閉鎖的關(guān)鍵區(qū)別在于墓赴,所有線程必須同時到達柵欄位置,才能繼續(xù)執(zhí)行航瞭。閉鎖用于等待事件诫硕,而柵欄用于等待其他線程。(柵欄則是所有線程相互等待沧奴,直到所有線程都到達某一點時才打開柵欄痘括,然后線程可以繼續(xù)執(zhí)行。)
CyclicBarrier 可以使一定數(shù)量的參與方反復(fù)地在柵欄位置匯集滔吠,它在并行迭代算法中非常有用纲菌。CyclicBarrier支持一個可選的Runnable參數(shù),當(dāng)線程通過柵欄時疮绷,runnable對象將被調(diào)用翰舌。構(gòu)造函數(shù)CyclicBarrier(int?parties,RunnablebarrierAction),當(dāng)線程在CyclicBarrier對象上調(diào)用await()方法時冬骚,柵欄的計數(shù)器將增加1椅贱,當(dāng)計數(shù)器為parties時懂算,柵欄將打開。
如:有這樣一個場景:五個人相約去鳥巢燒烤(不是爛大街的跑步了庇麦、/偷笑)计技,但是五個人是腿兒著去的(這不還是跑步嗎、/敲打/敲打)山橄,必須要等所有人都到達后才能開始燒烤垮媒,燒烤結(jié)束后各回各家。這里可以使用CyclicBarrier輕松實現(xiàn):
packagecom.java.nmq.cyclicbarrier;
importjava.util.concurrent.BrokenBarrierException;
importjava.util.concurrent.CyclicBarrier;
/**
* Created by niemengquan on 2017/4/13.
*/
public classRuningimplementsRunnable {
privateCyclicBarrierbarrier;
publicRuning(CyclicBarrier barrier){
this.barrier=barrier;
}
@Override
public voidrun() {
System.out.println(Thread.currentThread().getName()+":start to runing!");
try{
//模擬跑步的時間
Thread.sleep((long) (1000*Math.random()));
System.out.println(Thread.currentThread().getName()+":run done!");
//等待所有的人都跑完,到達約定的地點
barrier.await();
System.out.println(Thread.currentThread().getName()+":go home!");
}catch(InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e) {
e.printStackTrace();
}
}
}
?主類:
packagecom.java.nmq.cyclicbarrier;
importjava.util.concurrent.CyclicBarrier;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
/**
* 五個人相約去燒烤航棱,但要等所有人都到達目的地后才能開始睡雇。燒烤結(jié)束后各回各家
* Created by niemengquan on 2017/4/13.
*/
public classBarbecue {
public static voidmain(String[] args) {
CyclicBarrier barrier=newCyclicBarrier(5, newRunnable() {
@Override
public voidrun() {
try{
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("Everyone is here,starting BBQ!");
}
});
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(inti=0;i<5;i++){
executorService.execute(newRuning(barrier));
}
executorService.shutdown();
}
}
由于目前平臺對代碼支持的不是太好,為便于查看以上代碼都附上了截圖饮醇。
運行結(jié)果:
pool-1-thread-1:start to runing!
pool-1-thread-2:start to runing!
pool-1-thread-3:start to runing!
pool-1-thread-4:start to runing!
pool-1-thread-5:start to runing!
pool-1-thread-2:run done!
pool-1-thread-1:run done!
pool-1-thread-4:run done!
pool-1-thread-5:run done!
pool-1-thread-3:run done!
Everyone is here,starting BBQ!
pool-1-thread-2:go home!
pool-1-thread-1:go home!
pool-1-thread-4:go home!
pool-1-thread-5:go home!
pool-1-thread-3:go home!
Process finished with exit code 0