如何使用
java.util.concurrent.CyclicBarrier
是Java并发并发编程中的线程同步工具类,基于java.util.concurrent.locks.ReentrantLock
实现。
CyclicBarrier
工具类主要应用在如下场景:让一组线程同时到达栅栏位置才能开始执行。
应用示例:
代码语言:javascript复制public static void main(String[] args) {
// 使用CyclicBarrier模拟多线程同时到达栅栏位置之后才开始执行
int n = 10; // 线程数
CyclicBarrier barrier = new CyclicBarrier(n);
List resultList = new ArrayList(n);
List<Thread> threadList = new ArrayList<>(n);
for (int i = 0; i < n; i ) {
int index = i;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep((new Random().nextInt(10)) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println(String.format("线程%s准备好了", index));
barrier.await();
System.out.println(String.format("线程%s执行完毕!", index));
resultList.add(String.format("result%s", index));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
});
threadList.add(thread);
thread.start();
}
threadList.forEach(thread -> {
try {
// 等待线程执行完毕
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(String.format("所有线程都执行完毕:%s", resultList));
}
输出:
代码语言:javascript复制线程1准备好了
线程0准备好了
线程2准备好了
线程4准备好了
线程6准备好了
线程8准备好了
线程5准备好了
线程9准备好了
线程7准备好了
线程3准备好了
线程1执行完毕!
线程3执行完毕!
线程2执行完毕!
线程0执行完毕!
线程4执行完毕!
线程5执行完毕!
线程6执行完毕!
线程7执行完毕!
线程9执行完毕!
线程8执行完毕!
所有线程都执行完毕:[result1, result3, result2, result0, result4, result5, result6, result7, result9, result8]
与CountDownLatch的区别
关于CountDownLatch和CyclicBarrier的区别,主要体现在如下几个方面:
1.底层实现机制不同,CountDownLatch基于AQS,CyclicBarrier基于ReentrantLock。 2.CountDownLatch不可重复使用,CyclicBarrier可以重复使用。 3.应用场景不同:CountDownLatch用于等待一组线程执行完毕后继续后面的操作,CyclicBarrier用于让一组线程同时到达栅栏位置才能开始执行。
【参考】 CountdownLatch和CyclicBarrier的区别使用场景与具体实现