CyclicBarrier 也是 Java 中的一个同步工具类,它允许一组线程等待彼此达到一个共同的屏障点,直到所有线程都到达屏障点后才能继续执行。CyclicBarrier 可以被认为是一个可重用的计数器,每当一个线程到达屏障点时,计数器减 1,当计数器减为 0 时,表示所有线程都已到达屏障点,等待的线程可以继续执行。
API
CyclicBarrier
的常用方法有两个:
int await()
:表示一个线程已经到达屏障点,等待其他线程,如果所有线程都到达屏障点,则计数器重置,并且所有线程都继续执行;int await(long timeout, TimeUnit unit)
:表示一个线程已经到达屏障点,等待其他线程,如果所有线程都到达屏障点,则计数器重置,并且所有线程都继续执行;如果超时则抛出TimeoutException
异常。
以下是一个使用 CyclicBarrier 进行线程同步的示例代码:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
private static CyclicBarrier barrier = new CyclicBarrier(3);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
System.out.println("Task 1 is running");
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("Task 1 is completed");
});
Thread t2 = new Thread(() -> {
System.out.println("Task 2 is running");
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("Task 2 is completed");
});
Thread t3 = new Thread(() -> {
System.out.println("Task 3 is running");
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("Task 3 is completed");
});
t1.start();
t2.start();
t3.start();
Thread.sleep(1000);
System.out.println("All tasks are started");
t1.join();
t2.join();
t3.join();
System.out.println("All tasks are completed");
}
}
可重用表现在哪?
CyclicBarrier
是可重用的,表现在以下两个方面:
计数器重置
:当所有线程都到达屏障点后,计数器会被重置为初始值,即CyclicBarrier
对象创建时传入的值,这样CyclicBarrier
可以被用于多个屏障同步。在上述示例代码中,barrier
变量在初始化时传入的是 3,表示需要等待 3 个线程到达屏障点,如果需要再次使用该CyclicBarrier
对象进行同步,只需调用barrier.reset()
方法将计数器重置为 3 即可。异常处理
:如果一个线程在等待其他线程时被中断或超时,则CyclicBarrier
会抛出BrokenBarrierException
或TimeoutException
异常,这样可以对异常进行处理后继续使用CyclicBarrier
进行同步。在上述示例代码中,await()
方法可能会抛出BrokenBarrierException
异常,因此在调用await()
方法时需要进行异常处理。
CyclicBarrier 和 CountDownLatch 的区别是什么?
之前我们介绍了 CountDownLatch,似乎他们两个的作用是相同的,其实不然。
功能不同
CountDownLatch 被作用于线程等待其他线程完成,然后被阻塞的线程才继续执行,而 CyclicBarrier 通常用于将多个线程的执行阶段进行同步,以便它们可以在栅栏位置进行等待,直到所有线程都达到栅栏位置,然后所有线程可以同时执行后续操作。
重用能力不同
CyclicBarrier
可以被重用。一旦所有线程都到达栅栏位置并且栅栏被打破,它会自动重置,可以再次使用。
CountDownLatch
不能被重用。一旦计数器达到零并且门闩被打开,它不能再次使用。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于