CyclicBarrier
一、作用
- CyclicBarrier是并发编程的工具类,当一组线程需要全部到达某一个屏障点之后,后续的操作才可以继续执行,就可以使用CyclicBarrier,比如我们有四个数据采集线程和一个数据分析线程,我们需要在四个采集线程完成采集之后,再执行数据分析线程,可以借助CyclicBarrier来实现
二、代码
package com.intellif.mozping.concurrentutil.cyclicbarrierp;
import com.intellif.mozping.tools.SleepTools;
import java.util.concurrent.CyclicBarrier;
/**
* @author by mozping
* @Classname CyclicBarrierTest
* @Description 通过CyclicBarrier工具让一组线程到达指定点之后,再执行其他的操作
* 这里定义了MyWorkBeforeThread线程,表示任务前期处理,MyWorkAfterThread表示任务后期处理
* 定义了3个前期处理线程,需要3个线程都到达某个点之后,MyWorkAfterThread线程才能继续处理
* 观察现象发现,三个线程会在await处相互等待,到达后MyWorkAfterThread线程就会执行,
* 这里的初始化参数new CyclicBarrier(3, new MyWorkAfterThread());3代表有三个线程需要到达屏障点,
* MyWorkAfterThread表示到达屏障点后会执行的线程,这里注意如果是3个线程但是在主线程只创建了2个线程,
* 那么屏障点的条件一直不能被满足,线程会在await处阻塞,MyWorkAfterThread线程一直不会被调用
* @Date 2019/1/2 16:29
*/
public class CyclicBarrierTest {
//3表示需要到达屏障点的线程数量,MyWorkAfterThread表示到达屏障点后需要执行的任务
private static CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new MyWorkAfterThread());
private static class MyWorkBeforeThread extends Thread {
@Override
public void run() {
System.out.println("业务Before线程 [" + Thread.currentThread().getName() + "] 处理业务...");
//随机休眠10以内的时间
try {
SleepTools.randomSecond(10);
System.out.println("到达屏障点的线程数:" + (cyclicBarrier.getNumberWaiting() + 1));
cyclicBarrier.await();
System.out.println("业务Before线程 [" + Thread.currentThread().getName() + "] 等待完毕..." + System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
SleepTools.randomSecond(10);
System.out.println("业务Before线程 [" + Thread.currentThread().getName() + "] 处理其他的事情..." + System.currentTimeMillis());
}
}
private static class MyWorkAfterThread extends Thread {
@Override
public void run() {
System.out.println("业务After线程 [" + Thread.currentThread().getName() + "] 处理..." + System.currentTimeMillis());
}
}
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
new MyWorkBeforeThread().start();
}
}
}
三、Tips
- cyclicBarrier初始化的时候会指定到达屏障点的线程数,如果实际线程数小于该数目,就会一直在屏障点阻塞下去。
- 同样的await方法也可以指定超时时间,
- cyclicBarrier.getNumberWaiting()获取当前已经到达屏障点的线程数量,比如有三个线程需要到达屏障点,第一个线程到达后,该方法返回的就是1
- cyclicBarrier.reset:重置屏障