简介
CyclicBarrier翻译过来就是循环门闩的意思,CyclicBarrier类不仅有CountDownLatch所具有的功能,还可以实现屏障等待的功能,也就是阶段性同步,它在使用上的意义在于可以循环地实现线程要一起做任务的目标,而不是像CountDownLatch一样,仅仅支持一次线程与同步点阻塞的特性,API结构如下:
CyclicBarrier类和Semaphore及CountDownLatch一样,也是一个同步辅助类。它允许一组线程互相等待,直到到达某个公共屏障点,这些线程必须实时地等待,这种情况下就可以使用CyclicBarrier类来方便地实现这样的功能,CyclicBarrier的公共屏障点可以重用。
CyclicBarrier和CountDownLatch的区别:
1、CountDownLatch作用:一个线程或者多个线程,等待另外一个线程或多个线程完成某个事情之后才能继续执行
2、CyclicBarrier的作用:多个线程之间相互等待,任何一个线程完成之前,所有的线程都必须等待,所以对于CyclicBarrier来说,重点是“多个线程之间”任何一个线程没有完成任务,则所有线程都必须等待。
CountDownLatch和CyclicBarrier都有等待的功能,CountDownLatch是两个角色之间互相等待,而CyclicBarrier是同类互相等待,CountDownLatch的计数使用的是减法操作,CyclicBarrier是使用加法操作
API介绍
1、isBroken()方法的使用
isBroken方法时查询此屏障是否处于损坏状态
案例如下:
public class MyService {
private CyclicBarrier cyclicBarrier;
public MyService(CyclicBarrier cyclicBarrier) {
super();
this.cyclicBarrier = cyclicBarrier;
}
private void beginRun(int count) {
System.out.println(Thread.currentThread().getName()+"到了等待其他人都到了开始起跑");
try {
if (Thread.currentThread().getName().equals("Thread-2")) {
System.out.println("thread-2进来了");
Thread.sleep(1000);
Integer.parseInt("a");
}
cyclicBarrier.await();
System.out.println("都到了,开始跑!");
System.out.println(Thread.currentThread().getName()+"到达终点,并结束第"+count+"赛段");
} catch (InterruptedException e) {
System.out.println("进入了InterruptedException"+cyclicBarrier.isBroken());
e.printStackTrace();
} catch (BrokenBarrierException e) {
System.out.println("进入了BrokenBarrierException"+cyclicBarrier.isBroken());
e.printStackTrace();
}
}
public void testA() {
for (int i = 0; i < 1; i++) {
beginRun(i+1);
}
}
}
public class MyThread extends Thread {
private MyService myService;
public MyThread(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
myService.testA();
}
}
public class Run {
public static void main(String[] args) {
int parties = 4;
CyclicBarrier cyclicBarrier = new CyclicBarrier(parties, ()->{
System.out.println("都到了");
}) ;
MyService myService = new MyService(cyclicBarrier);
MyThread[] threadArray = new MyThread[4];
for (int i = 0; i < threadArray.length; i++) {
threadArray[i] = new MyThread(myService);
threadArray[i].start();
}
}
}
运行结果如下:
从程序的运行结果来看,有一个线程出现异常错误,则其他线程继续等待,并不影响程序运行的主流程
更改Myservice类中的部分代码,代码由原来出现异常改成了interrupt中断:
if (Thread.currentThread().getName().equals("Thread-2")) {
System.out.println("thread-2进来了");
Thread.sleep(5000);
Thread.currentThread().interrupt();
}
运行结果如下:
从运行结果来看,全部线程都进入了catch语句块,其中Thread-2线程进入了Interrupted Exception的catch语句块,其它3个线程进入了BrokenBarrierException的catch语句块,
CyclicBarrier类对线程的中断interrupte处理会使用全有或者全无的破坏模型,意思是如果有一个线程由于中断或者超时提前离开了屏障点,其它所有在屏障点等待的线程也会抛出BrokerBarrierException或者InterruptedException异常,并且离开屏障点。
来源:CSDN
作者:goal升
链接:https://blog.csdn.net/lazy__Feng/article/details/104223413