CyclicBarrier ,可循环(计数器可以重置)利用的同步屏障,线程到达一个屏障会阻塞,到达屏障的线程数达到设置的值时,所有被屏障阻塞的线程开始执行。
1. 概述
构造函数:public CyclicBarrier(int parties),设置初始值。
public CyclicBarrier(int parties, Runnable barrierAction),优先执行 barrierAction。
设置屏障方法:public int await()
有时间限制的设置屏障方法,超时则不再阻塞:public int await(long timeout, TimeUnit unit)
屏障是否损坏:阻塞的线程被中断(超时也会损坏屏障),就损坏了,损坏返回true:public boolean isBroken()
重置计数器:public void reset()。
当前等待的数量:public int getNumberWaiting()
2. 测试代码
设置初始值为2 。
package util;import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierStudy implements Runnable{static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);public static void main(String[] args) throws BrokenBarrierException, InterruptedException {new Thread(new CyclicBarrierStudy()).start();cyclicBarrier.await();System.out.println(2);}@Overridepublic void run() {try {cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println(1);}
}
运行截图如下,屏障处的线程执行顺序不定。
设置初始值为3(其他代码不变)。
static CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
发生阻塞,因为到达屏障的线程数需要达到设置的值3,如下图所示。
有时间限制的设置屏障方法,超时则不再阻塞:public int await(long timeout, TimeUnit unit)。
屏障是否损坏,阻塞的线程被中断(超时也会损坏屏障),就损坏了,损坏返回true:public boolean isBroken()。
package util;import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;public class CyclicBarrierStudy implements Runnable{static CyclicBarrier cyclicBarrier = new CyclicBarrier(3);public static void main(String[] args) throws BrokenBarrierException, InterruptedException {new Thread(new CyclicBarrierStudy()).start();try {cyclicBarrier.await(1000, TimeUnit.MILLISECONDS);} catch (TimeoutException e) {e.printStackTrace();}System.out.println("step1 " + cyclicBarrier.isBroken());}@Overridepublic void run() {try {try {cyclicBarrier.await(1000, TimeUnit.MILLISECONDS);} catch (TimeoutException e) {e.printStackTrace();}} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println("step2 " + cyclicBarrier.isBroken());}
}
运行截图,超时等待(不再阻塞),屏障破坏。
参考文献:
- Java并发编程的艺术 / 方腾飞,魏鹏,魏晓明著 . ——北京:机械工业出版社,2015.7