Waitgroups in Java
Our example demonstrates how to wait for multiple threads to finish using a CountDownLatch
. This is similar to the concept of WaitGroups in other languages.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class CountDownLatchExample {
// This is the method we'll run in every thread.
private static void worker(int id, CountDownLatch latch) {
try {
System.out.printf("Worker %d starting%n", id);
// Sleep to simulate an expensive task.
TimeUnit.SECONDS.sleep(1);
System.out.printf("Worker %d done%n", id);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
// Signal that this worker is done.
latch.countDown();
}
}
public static void main(String[] args) throws InterruptedException {
// This CountDownLatch is used to wait for all the
// threads launched here to finish.
CountDownLatch latch = new CountDownLatch(5);
// Launch several threads and decrement the CountDownLatch
// counter for each.
for (int i = 1; i <= 5; i++) {
final int workerId = i;
new Thread(() -> worker(workerId, latch)).start();
}
// Block until the CountDownLatch counter goes back to 0;
// all the workers notified they're done.
latch.await();
// Note that this approach has no straightforward way
// to propagate exceptions from workers. For more
// advanced use cases, consider using an ExecutorService
// with Future objects.
}
}
To run the program:
$ javac CountDownLatchExample.java
$ java CountDownLatchExample
Worker 1 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 5 starting
Worker 3 done
Worker 1 done
Worker 2 done
Worker 4 done
Worker 5 done
The order of workers starting up and finishing is likely to be different for each invocation.
In this Java version:
We use a
CountDownLatch
instead of a WaitGroup. TheCountDownLatch
is initialized with the number of threads we’re waiting for.Each worker thread calls
countDown()
on the latch when it’s done, similar towg.Done()
in the original example.The main thread waits for all workers to finish using
latch.await()
, which is equivalent towg.Wait()
.We use Java’s built-in
Thread
class to create and start new threads, rather than goroutines.Error handling is done via try-catch blocks. For more advanced scenarios, you might want to use an
ExecutorService
andFuture
objects to handle exceptions and results from worker threads.
This example demonstrates how to coordinate multiple threads in Java, achieving similar functionality to the original WaitGroups example.