Java 语言 并发工具类 CountDownLatch/CyclicBarrier 组合使用 多阶段任务同步

Java阿木 发布于 24 天前 4 次阅读


摘要:

在Java并发编程中,多阶段任务同步是一个常见且复杂的问题。CountDownLatch和CyclicBarrier是Java并发工具类库中用于解决此类问题的两种重要工具。本文将深入探讨这两种工具类的原理和使用方法,并通过实际案例展示它们在多阶段任务同步中的应用。

一、

多阶段任务同步是指在并发编程中,多个任务需要按照一定的顺序执行,且每个阶段完成后才能进入下一个阶段。这种同步机制在分布式系统、网络编程、多线程应用等领域有着广泛的应用。Java并发工具类CountDownLatch和CyclicBarrier正是为了解决这类问题而设计的。

二、CountDownLatch

CountDownLatch是一个同步辅助类,允许一个或多个线程等待其他线程完成操作。它通过一个计数器来控制线程的执行。当计数器值为0时,所有等待的线程将被释放。

1. CountDownLatch的原理

CountDownLatch内部维护一个计数器,初始值为指定值。每当一个线程完成某个阶段后,它会调用countDown()方法,将计数器减1。当计数器为0时,所有等待的线程将被唤醒。

2. CountDownLatch的使用方法

java

public class CountDownLatchExample {


private final int totalThreadCount;


private final CountDownLatch latch;

public CountDownLatchExample(int totalThreadCount) {


this.totalThreadCount = totalThreadCount;


this.latch = new CountDownLatch(totalThreadCount);


}

public void doWork() {


for (int i = 0; i < totalThreadCount; i++) {


new Thread(() -> {


try {


// 模拟任务执行


Thread.sleep(1000);


System.out.println(Thread.currentThread().getName() + " completed.");


} catch (InterruptedException e) {


e.printStackTrace();


} finally {


latch.countDown();


}


}).start();


}

try {


// 等待所有线程完成


latch.await();


System.out.println("All threads completed.");


} catch (InterruptedException e) {


e.printStackTrace();


}


}

public static void main(String[] args) {


CountDownLatchExample example = new CountDownLatchExample(5);


example.doWork();


}


}


三、CyclicBarrier

CyclicBarrier是一个同步辅助类,它允许一组线程在到达某个屏障点(barrier)时被阻塞,直到所有线程都到达屏障点后,这些线程才会继续执行。

1. CyclicBarrier的原理

CyclicBarrier内部维护一个计数器,初始值为线程数。每当一个线程到达屏障点时,它会调用await()方法,将计数器减1。当计数器为0时,所有等待的线程将被唤醒,并继续执行。

2. CyclicBarrier的使用方法

java

public class CyclicBarrierExample {


private final int totalThreadCount;


private final CyclicBarrier barrier;

public CyclicBarrierExample(int totalThreadCount) {


this.totalThreadCount = totalThreadCount;


this.barrier = new CyclicBarrier(totalThreadCount, () -> {


System.out.println("Barrier reached by all threads.");


});


}

public void doWork() {


for (int i = 0; i < totalThreadCount; i++) {


new Thread(() -> {


try {


// 模拟任务执行


Thread.sleep(1000);


System.out.println(Thread.currentThread().getName() + " reached the barrier.");


barrier.await();


} catch (InterruptedException | BrokenBarrierException e) {


e.printStackTrace();


}


}).start();


}


}

public static void main(String[] args) {


CyclicBarrierExample example = new CyclicBarrierExample(5);


example.doWork();


}


}


四、CountDownLatch和CyclicBarrier的组合使用

在实际应用中,CountDownLatch和CyclicBarrier可以组合使用,以实现更复杂的同步逻辑。

java

public class CombinedExample {


private final int totalThreadCount;


private final CountDownLatch latch;


private final CyclicBarrier barrier;

public CombinedExample(int totalThreadCount) {


this.totalThreadCount = totalThreadCount;


this.latch = new CountDownLatch(totalThreadCount);


this.barrier = new CyclicBarrier(totalThreadCount, () -> {


System.out.println("Barrier reached by all threads.");


});


}

public void doWork() {


for (int i = 0; i < totalThreadCount; i++) {


new Thread(() -> {


try {


// 模拟任务执行


Thread.sleep(1000);


System.out.println(Thread.currentThread().getName() + " reached the barrier.");


barrier.await();


latch.countDown();


} catch (InterruptedException | BrokenBarrierException e) {


e.printStackTrace();


}


}).start();


}

try {


// 等待所有线程完成


latch.await();


System.out.println("All threads completed.");


} catch (InterruptedException e) {


e.printStackTrace();


}


}

public static void main(String[] args) {


CombinedExample example = new CombinedExample(5);


example.doWork();


}


}


五、总结

CountDownLatch和CyclicBarrier是Java并发编程中常用的工具类,用于解决多阶段任务同步问题。通过本文的介绍和示例代码,我们可以了解到这两种工具类的原理和使用方法。在实际应用中,可以根据具体需求选择合适的工具类,或者将它们组合使用,以实现复杂的同步逻辑。