线程同步辅助类CyclicBarrier

2017-04-13  本文已影响0人  霁暖阁

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

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();

}

}

}

Running.java

 主类:

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));

}

executorService.shutdown();

}

}

Barbecue.java

由于目前平台对代码支持的不是太好,为便于查看以上代码都附上了截图。

运行结果:

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

运行结果
上一篇下一篇

猜你喜欢

热点阅读