一、概述
同步屏障可以使多条线程彼此等待,直到抵达某个公共的屏障点。线程之间彼此等待时已经抵达公共屏障点的线程不会继续往下执行,会在所有线程抵达公共屏障点之前一直阻塞。CyclicBarrierDemo对象可以重用,这点与上一篇中的CountDownLatch对象不同,CountDowLatch时不可重用的。
二、主要方法
CyclicBarrier(int parties):初始化一个包含指定parties数目的CyclicBarrier对象
int await() throws InterruptedException, BrokenBarrierException:强制阻塞线程,一直等待所有的parties线程都在同步屏障上调用了await()方法
int await(long time, DateUtil util):指定线程的等待时间,如果超时会抛出异常
void reset():重置对象,如果此时有线程在这个对象上阻塞,则会抛出异常
int getNumberWaiting(): 返回阻塞的线程数量。
三、代码示例
高速公路的建造:高速公路的建造不是从头到尾建造的,高速公路在规划后之后,会将规划路线分段施工,一般情况下一条完整的高速公路在施工时是好几段同时施工的。下面我们使用CyclicBarrierDemo对象来实现建造一条完整高速公路的场景。
如上图中所示,假如上面三段是一条完成的高速公路,现在分三段施工,每一段完成就是抵达了公共屏障点。
package com.scott.current;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
/**
* 一个CyclicBarrier的简单例子
*
* 模拟高速公路建造:高速公路的建造是分段进行的,会将之前规划好的高速公路分割为 N 段
* 然后可能是 M 段一起施工,当 N 段全部完成后即代表该调高速公路建造完成
* @author Scott
*/
public class CyclicBarrierDemo {
/** 假设高速公路被分割为 3 段 */
private final static int N = 3;
public static void main(String[] args) {
String[] roadNameArray = new String[]{"广梧高速", "广昆高速", "广湛高速"};
// 构建指定执行共同目标线程数量的同步屏障对象
CyclicBarrier barrier = new CyclicBarrier(N);
// N 段高速公路同时开工建造
for(int i = 0; i < roadNameArray.length; i++) {
new BuildRoad(barrier, roadNameArray[i]).start();
}
}
/**
* 建造一段高速公路
*/
static class BuildRoad extends Thread{
// 同步屏障
private CyclicBarrier cyclicBarrier;
private BuildRoad(CyclicBarrier cyclicBarrier, String name) {
this.cyclicBarrier = cyclicBarrier;
setName(name);
}
@Override
public void run() {
System.out.println("线程:" + Thread.currentThread().getName() + "正在建造中..." + "\t" + System.currentTimeMillis());
try {
// 睡眠来模拟每段的建造
Thread.sleep((long) (Math.random() * 20000));
System.out.println("线程"+Thread.currentThread().getName()+"建造完成。" + "\t" + System.currentTimeMillis());
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "高速公路建造完成,准备通车!!!" + "\t" + System.currentTimeMillis());
}
}
}
执行结果:
按照这个场景,上述代码中一共是三条线程,每条线程执行到 await() 方法就是抵达了公共屏障点,也就是场景中的其中一段高速公共施工完成了。从结果里面可以看到,没有全部抵达公共屏障点之前,抵达了的线程都是处于阻塞状态的。
这里面涉及到多条线程和一个共享变量(CyclicBarrier barrier)
上述就是关于CyclicBarrier对象的简单使用。