Golang 的 Waitgroup 锁用 Java的话要怎么实现?

发布于:2025-03-27 ⋅ 阅读:(29) ⋅ 点赞:(0)

在 Go 语言里,sync.WaitGroup 主要用于等待一组 goroutine 完成执行。在 Java 中,与之功能对应的实现方式有多种,下面为你详细介绍。

方式一:使用 CountDownLatch

CountDownLatch 是 Java 并发包 java.util.concurrent 里的一个同步工具类,它允许一个或多个线程等待其他线程完成操作。以下是示例代码:

java

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        int numThreads = 3;
        CountDownLatch latch = new CountDownLatch(numThreads);

        for (int i = 0; i < numThreads; i++) {
            final int threadId = i;
            new Thread(() -> {
                try {
                    System.out.println("Thread " + threadId + " is working.");
                    // 模拟工作
                    Thread.sleep(1000); 
                    System.out.println("Thread " + threadId + " has finished.");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    // 减少计数
                    latch.countDown(); 
                }
            }).start();
        }

        // 等待所有线程完成
        latch.await(); 
        System.out.println("All threads have finished their work.");
    }
}

上述代码里,CountDownLatch 初始计数为 numThreads,也就是线程的数量。每个线程完成工作后,会调用 countDown() 方法使计数减 1。主线程调用 await() 方法,会一直阻塞直到计数变为 0,这意味着所有线程都完成了工作。

方式二:使用 CyclicBarrier

CyclicBarrier 同样是 java.util.concurrent 包中的同步工具类,它能让一组线程在到达某个屏障(同步点)时相互等待。以下是示例代码:

java

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    public static void main(String[] args) {
        int numThreads = 3;
        CyclicBarrier barrier = new CyclicBarrier(numThreads, () -> {
            System.out.println("All threads have reached the barrier.");
        });

        for (int i = 0; i < numThreads; i++) {
            final int threadId = i;
            new Thread(() -> {
                try {
                    System.out.println("Thread " + threadId + " is working.");
                    // 模拟工作
                    Thread.sleep(1000); 
                    System.out.println("Thread " + threadId + " has reached the barrier.");
                    // 等待其他线程到达屏障
                    barrier.await(); 
                } catch (InterruptedException | BrokenBarrierException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
        }
    }
}

在这个例子中,CyclicBarrier 初始计数为 numThreads。每个线程完成工作后,会调用 await() 方法等待其他线程。当所有线程都调用了 await() 方法,屏障就会被打破,并且可以执行一个可选的屏障操作。

综上所述,CountDownLatch 更适合一个或多个线程等待其他线程完成操作的场景,而 CyclicBarrier 更适合一组线程相互等待到达某个同步点的场景。你可以依据具体需求选择合适的工具类。