前言
在多线程编程中,同步工具是确保线程之间协同工作的重要组成部分。
CyclicBarrier(循环屏障)是Java中的一个强大的同步工具,它允许一组线程在达到某个共同点之前互相等待。
在本文中,我们将深入探讨CyclicBarrier的源码实现以及提供一些示例,以帮助您更好地理解和应用这个有趣的同步工具。
CyclicBarrier源码解析以及示例
主要成员变量
public class CyclicBarrier {
private final ReentrantLock lock = new ReentrantLock();
private final Condition trip = lock.newCondition();
private final int parties;
private int count;
private final Runnable barrierCommand;
}
lock
: 用于控制并发访问的重入锁。trip
: 条件变量,用于在屏障点上等待。parties
: 表示需要等待的线程数。count
: 表示当前已经到达屏障点的线程数。barrierCommand
: 在所有线程到达屏障点之后执行的命令,可以为null。
核心方法
await
方法
public int await() throws InterruptedException, BrokenBarrierException {
try {
lock.lock();
if (Thread.interrupted())
throw new InterruptedException();
int index = --count;
if (index == 0) { // 如果是最后一个到达的线程
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
return 0;
} finally {
if (!ranAction)
breakBarrier(); // 执行失败,重置屏障状态
}
}
while (index > 0) {
try {
trip.await();
} catch (InterruptedException ie) {
if (index == 1 && !broken)
breakBarrier();
throw ie;
}
}
if (broken)
throw new BrokenBarrierException();
return index;
} finally {
lock.unlock();
}
}
上述代码主要完成以下几个任务:
1.减小计数器,表示有一个线程到达了屏障点。
2.如果是最后一个到达的线程,执行屏障命令(如果有),然后唤醒所有等待的线程。
3.如果不是最后一个到达的线程,进入等待状态,直到被唤醒。
4.处理中断异常和屏障破坏异常。
应用场景
任务分解与合并
当一个大任务可以分解为多个子任务,每个子任务独立执行,但在某个点上需要等待所有子任务完成后再继续执行父任务。CyclicBarrier可以用来同步这些子任务的执行,确保它们在特定的屏障点上等待&#