一、关于CyclicBarrier的举例
- 比如我们打篮球前首先得把人交齐,人到齐了才可以开始玩,玩的过程中每个人有不同的角色,这里的人相当于不同的线程,角色所担当的任务相当于线程执行的任务示例代码如下
public class MyCyclicBarrier {
private static CyclicBarrier barrier = new CyclicBarrier(4,()->
// 相当于裁判发令可以打球了
System.out.println("人都来齐了可以开始打球了"));
public static void main(String[] args) {
new Thread(()->{
try {
/*等大家都到齐,人一旦到齐就可以开打球了*/
Thread.sleep(1000);
barrier.await();
System.out.println("我是控球后卫我正在控球");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
try {
/*等大家都到齐,人一旦到齐就可以开打球了*/
barrier.await();
Thread.sleep(1000);
System.out.println("我是得分后卫我正在投篮");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
try {
/*等大家都到齐,人一旦到齐就可以开打球了*/
barrier.await();
Thread.sleep(1000);
System.out.println("我是大前锋我正配个各位");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
try {
/*等大家都到齐,人一旦到齐就可以开打球了*/
barrier.await();
Thread.sleep(1000);
System.out.println("我是中锋我正在抢夺篮板球");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
代码运行结果
二、CyclicBarrier和CountDownLatch的比较
- CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置,因此CyclicBarrier能处理更为复杂的业务场景,比如计算发生错误时,可以重置计数器,并让所有涉及到达线程重新执行一次
- CyclicBarrier可以通过getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量,通过isBroken来判断阻塞的线程是否被中断
- CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程
关于CountDownLatch可以参考此篇文章