版权声明:转载注明出处 https://blog.csdn.net/jy02268879/article/details/86010106
CyclicBarrier是一个同步工具类,它允许一组线程互相等待,直到到达某个公共屏障点。
与CountDownLatch不同的是该barrier在释放等待线程后可以重用,所以称它为循环(Cyclic)的屏障(Barrier)。
CyclicBarrier支持一个可选的Runnable命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。
代码示例
package com.sid.thread.CyclicBarrierTest;
import java.util.Date;
import java.util.concurrent.CyclicBarrier;
/**
* @program: thread-test
* @description: 让多个线程互相等待某一事件的发生,然后同时被唤醒。
* CyclicBarrier可以译为循环屏障,也有类似的功能。
* CyclicBarrier可以在构造时指定需要在屏障前执行await的个数,所有对await的调用都会等待
* 示例:有五个线程都调用barrier.await()了之后,该五个线程一起唤醒
* @author: Sid
* @date: 2018-11-27 14:34
* @since: 1.0
**/
public class CyclicBarrierDemo {
public static void main(String[] args) {
int totalThread = 5;
/**
* CyclicBarrier可以在构造时指定需要在屏障前执行await的个数,所有对await的调用都会等待
*/
CyclicBarrier barrier = new CyclicBarrier(totalThread,new Runnable() {
public void run() {
System.out.println(String.format("%s\t%s %s", new Date(), Thread.currentThread().getName(), " merge runnable"));
}});
for(int i = 0; i < totalThread; i++) {
new Thread(() -> {
System.out.println(String.format("%s\t%s %s", new Date(), Thread.currentThread().getName(), " is waiting"));
try {
/**
* await() 等待其它参与方的到来(调用await())。
* 如果当前调用是最后一个await,则唤醒所有其它的线程的等待,
* 并且如果在构造CyclicBarrier时指定了action,当前线程会去执行该action,
* 然后该方法返回该线程调用await的次序(getParties()-1说明该线程是第一个调用await的,0说明该线程是最后一个执行await的),
* 接着该线程继续执行await后的代码。
* 如果该调用不是最后一个调用,则阻塞等待;
* 如果等待过程中,当前线程被中断,
* 则抛出InterruptedException;
* 如果等待过程中,其它等待的线程被中断,或者其它线程等待超时,
* 或者该barrier被reset,或者当前线程在执行barrier构造时注册的action时因为抛出异常而失败,
* 则抛出BrokenBarrierException。
*
* await(long timeout, TimeUnit unit) 与await()唯一的不同点在于设置了等待超时时间,等待超时时会抛出TimeoutException。
*
* reset() 该方法会将该barrier重置为它的初始状态,并使得所有对该barrier的await调用抛出BrokenBarrierException。
* */
int await = barrier.await();
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(String.format("%s\t%s %s", new Date(), Thread.currentThread().getName(), "ended"));
}).start();
}
}
}
运行结果
这里可以看到,最后抵达屏障的线程执行了CyclicBarrier初始化时的Runnable命令。