介绍
本质:线程到达栅栏后等待,直到n个线程都到达,然后n个线程开始奔向下一个栅栏
原理:
使用ReentrantLock和Condition实现
使用DEMO
我有3个线程,每个线程的执行分为3个阶段,我希望所有都执行完前一个阶段后再一起执行下一个阶段。
public class Hello {
public static void main(String[] args) throws InterruptedException {
//某个阶段完成后执行的动作
Runnable barrierAction = () -> System.out.println("==================");
//设置3个成员
CyclicBarrier barrier = new CyclicBarrier(3, barrierAction);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " 开始阶段1");
barrier.await();
System.out.println(Thread.currentThread().getName() + " 开始阶段2");
barrier.await();
System.out.println(Thread.currentThread().getName() + " 开始阶段3");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
输出:
Thread-0 开始阶段1
Thread-1 开始阶段1
Thread-2 开始阶段1
==================
Thread-2 开始阶段2
Thread-0 开始阶段2
Thread-1 开始阶段2
==================
Thread-1 开始阶段3
Thread-2 开始阶段3
Thread-0 开始阶段3
自己实现
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class MyCyclicBarrier {
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private final int threadCount;
private int currentThreadNumber;
private final Runnable barrierAction;
public MyCyclicBarrier(int threadCount, Runnable barrierAction) {
this.threadCount = threadCount;
this.barrierAction = barrierAction;
}
public void await() {
lock.lock();
try {
currentThreadNumber++;
if (currentThreadNumber == threadCount) {
//执行动作
if (barrierAction != null) {
barrierAction.run();
}
//重新计数,必须先置0再唤醒
currentThreadNumber = 0;
//唤醒所有线程
condition.signalAll();
} else {
//如果数目还没有达到则需要阻塞线程
condition.await();
}
} catch (Exception ignored) {
} finally {
lock.unlock();
}
}
}