线程同步辅助类CyclicBarrier
CyclicBarrier国内有些人翻译做栅栏。
栅栏(Barrier)类似于闭锁,它能阻塞一组线程直到某个事件发生。栅栏与闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。(栅栏则是所有线程相互等待,直到所有线程都到达某一点时才打开栅栏,然后线程可以继续执行。)
CyclicBarrier 可以使一定数量的参与方反复地在栅栏位置汇集,它在并行迭代算法中非常有用。CyclicBarrier支持一个可选的Runnable参数,当线程通过栅栏时,runnable对象将被调用。构造函数CyclicBarrier(int parties,RunnablebarrierAction),当线程在CyclicBarrier对象上调用await()方法时,栅栏的计数器将增加1,当计数器为parties时,栅栏将打开。
如:有这样一个场景:五个人相约去鸟巢烧烤(不是烂大街的跑步了、/偷笑),但是五个人是腿儿着去的(这不还是跑步吗、/敲打/敲打),必须要等所有人都到达后才能开始烧烤,烧烤结束后各回各家。这里可以使用CyclicBarrier轻松实现:
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
Running.javapublic 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;
/**
* 五个人相约去烧烤,但要等所有人都到达目的地后才能开始。烧烤结束后各回各家
* 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));
}
Barbecue.javaexecutorService.shutdown();
}
}
由于目前平台对代码支持的不是太好,为便于查看以上代码都附上了截图。
运行结果:
运行结果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