循环栅栏CyclicBarrier是多线程并发控制实用工具。其功能跟CountDownLatch相似,可以理解为时增强版可循环使用的CountDownLatch。
为什么这个工具叫循环栅栏这个名字?是因为该工具的功能就是当一个线程调用了cyclicBarrier.await()方法时,就会被栅栏拦住,进入等待执行状态,直到满足栅栏要求数量的线程到达栅栏时,才会对这一批线程一起放行。放行后有其他线程到达栅栏,那么就会进入新一轮的等待和放行(可循环使用)。比如说该栅栏CyclicBarrier设置阈值为5,那么就是要求当有5个线程到达该栅栏时,才会对这5个线程一起放行。之后再有线程到达栅栏,则进入新一轮。
CyclicBarrier主要方法如下:
/**
* 构造方法,指定阈值
*/
public CyclicBarrier(int parties)
/**
* 调用该方法的线程会进入等待状态,同时循环栅栏等待线程数+1,当达到指定阈值的线程数后,一起放行
* 返回当前进入栅栏线程的index{@code getParties() - 1}
*/
public int await()
简单示例代码如下:
/**
* CyclicBarrier 循环栅栏
* 当线程调用cyclicBarrier.await()时,该线程会进入等待状态,cyclicBarrier中的等待线程数量count +1
* 直到调用该方法的线程数量达到 cyclicBarrier的阈值时,这一批线程会同时唤醒,继续运行。
* 此时cyclicBarrier中的等待线程数量也会清零,当有线程再次调用await()时,重新计数,进入新一轮。
*
* @author DangerShi
*/
public class CyclicBarrierDemo {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
for (int i = 0; i < 4; i++) {
Thread.sleep(1000);
new Thread(new BarrierThread(cyclicBarrier)).start();
}
}
}
class BarrierThread implements Runnable {
private CyclicBarrier cyclicBarrier;
BarrierThread(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println("await threads = " + cyclicBarrier.getNumberWaiting());
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " finished");
}
}
参考:《Java高并发程序设计》 葛一鸣、郭超 编著