- CyclicBarrier和CountDownLatch的不同是
- CyclicBarrier的计数器有自动重置的功能
- CyclicBarrier有提供回调函数的功能,当计数器减到0时,会调用这个回调函数。
- 简单使用例子:
public class CyclicBarrierDemo {
static CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
@Override
public void run() {
signal();
}
});
static void signal() {
System.out.println("---------------------------------执行完毕,重新执行---------------------------------");
}
public static void main(String[] args) {
Thread T1 = new Thread(()->{
for (;;) {
try {
long startDate = System.currentTimeMillis();
Thread.sleep(1000);
cyclicBarrier.await();
long endDate = System.currentTimeMillis();
long second = (endDate - startDate) / 1000;
System.out.println("线程1等待完毕,耗时:"+ second + "秒");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
});
T1.start();
Thread T2 = new Thread(()->{
for (;;) {
try {
long startDate = System.currentTimeMillis();
Thread.sleep(5000);
cyclicBarrier.await();
long endDate = System.currentTimeMillis();
long second = (endDate - startDate) / 1000;
System.out.println("线程2等待完毕,耗时:"+ second + "秒");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
});
T2.start();
}
}
-
输出结果
---------------------------------执行完毕,重新执行---------------------------------
线程2等待完毕,耗时:5秒
线程1等待完毕,耗时:5秒
---------------------------------执行完毕,重新执行---------------------------------
线程1等待完毕,耗时:5秒
线程2等待完毕,耗时:5秒
---------------------------------执行完毕,重新执行---------------------------------
线程2等待完毕,耗时:5秒
线程1等待完毕,耗时:5秒
---------------------------------执行完毕,重新执行---------------------------------
线程1等待完毕,耗时:5秒
线程2等待完毕,耗时:5秒 -
可以看到输出的结果不管休眠1s还是5s,都是会等CyclicBarrier的计数器为0时统一执行,先触发回调函数,再执行cyclicBarrier.await();代码项目的逻辑。