CyclicBarrier的使用

简介

CyclicBarrier翻译过来就是循环门闩的意思,CyclicBarrier类不仅有CountDownLatch所具有的功能,还可以实现屏障等待的功能,也就是阶段性同步,它在使用上的意义在于可以循环地实现线程要一起做任务的目标,而不是像CountDownLatch一样,仅仅支持一次线程与同步点阻塞的特性,API结构如下:

CyclicBarrier的使用_第1张图片

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

运行结果如下:
CyclicBarrier的使用_第2张图片

从程序的运行结果来看,有一个线程出现异常错误,则其他线程继续等待,并不影响程序运行的主流程
更改Myservice类中的部分代码,代码由原来出现异常改成了interrupt中断:
if (Thread.currentThread().getName().equals("Thread-2")) {
				System.out.println("thread-2进来了");
				Thread.sleep(5000);
				Thread.currentThread().interrupt();
			}

运行结果如下:
CyclicBarrier的使用_第3张图片

从运行结果来看,全部线程都进入了catch语句块,其中Thread-2线程进入了Interrupted Exception的catch语句块,其它3个线程进入了BrokenBarrierException的catch语句块,
CyclicBarrier类对线程的中断interrupte处理会使用全有或者全无的破坏模型,意思是如果有一个线程由于中断或者超时提前离开了屏障点,其它所有在屏障点等待的线程也会抛出BrokerBarrierException或者InterruptedException异常,并且离开屏障点。

你可能感兴趣的:(JUC学习笔记,Java,java,多线程,thread,并发编程)