Using Java's CountDownLatch for multi-threading

CountDownLatch is a class that was added to the java.util.concurrent package in Java 1.5. As its Javadoc states it "allows one or more threads to wait until a set of operations being performed in other threads completes". I never had the chance to use it until this week, but now that I have, I fully appreciate its power!

A CountDownLatch is instantiated with a positive count and provides a countDown method that decrements the count. The await method "causes the current thread to wait until the latch has counted down to zero". (The maximum amount of time that await actually waits can be configured, although I didn't use that feature.)

I use a CountDownLatch when I am gathering results on a number of hosts and aggregating the results from each host into a single object that is returned to the caller. This is a perfect place to use a CountDownLatch because the number of hosts can be used as the count that is passed to its constructor.

Here's my code (with error-handling removed for brevity):

  public Results getResultsOnAllHosts()
{
final List<String> hosts = getHosts();
final CountDownLatch countDownLatch = new CountDownLatch(hosts.size());
final List<GetResultsOnHostThread> threads =
getThreadsThatAreStarted(hosts, countDownLatch);
waitForAllThreadsToFinish(countDownLatch);
return aggregateResults(threads);
}


private List<GetResultsOnHostThread> getThreadsThatAreStarted(
final List<String> hosts, final CountDownLatch countDownLatch)
{
final List<GetResultsOnHostThread> threads =
Lists.newArrayListWithCapacity(hosts.size());
for (final String host : hosts)
{
final GetResultsOnHostThread thread =
new GetResultsOnHostThread(host, countDownLatch);
thread.start();
threads.add(thread);
}
return threads;
}

private void waitForAllThreadsToFinish(final CountDownLatch countDownLatch)
{
try
{
countDownLatch.await();
}
catch (final InterruptedException e)
{
Thread.currentThread().interrupt();
}
}

class GetResultsOnHostThread extends Thread
{
private final String host;
private final CountDownLatch countDownLatch;
private ResultsOnOneHost resultsOnThisHost;

GetResultsOnHostThread(final String host, final CountDownLatch countDownLatch)
{
this.host = host;
this.countDownLatch = countDownLatch;
}

@Override
public void run()
{
try
{
results = getResultsOnHost(this.host);
}
finally
{
countDownLatch.countDown();
}
}
}