import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.Random; /** * A given number of threads, contenders, generate a random * number. The contender who submitts the largest value wins. * * In order for a conteder to know if they won, they must be * able to wait untill all contenders are done. */ public class CountDownExample { private static final int NUM_THREADS = 10; public static void main(String[] args) { // Make barrier, set to wait for NUM_THREADS call to countDown(). CountDownLatch allDoneBarrier = new CountDownLatch(...); // Make and start threads. No need to store threads for waiting, // we can use the barrier for this. KeepLargestMonitor monitor = new KeepLargestMonitor(); for (int i = 0; i < NUM_THREADS; i++) { ... } // wait for all contenders to be done try { ... } catch (InterruptedException e) {} System.out.println("The largest number: " + monitor.getLargest()); } } /* Monitor to save the largest recieved value. */ class KeepLargestMonitor { private final Lock lock = new ReentrantLock(); private int largest; public int getLargest() { return largest; } public void giveNumber(int number) { ... try { largest = Math.max(largest, number); } finally { lock.unlock(); } } } class Contender implements Runnable { private final KeepLargestMonitor monitor; private final CountDownLatch allDoneBarrier; private final int id; public Contender(KeepLargestMonitor monitor, CountDownLatch allDoneBarrier, int id) { this.id = id; this.monitor = monitor; this.allDoneBarrier = allDoneBarrier; } public void ...() { Random random = new Random(); int number = random.nextInt(100); // max of 100 System.out.printf("Thread #%d generated number: %d\n", id, number); monitor.giveNumber(number); // Report that done, wait for the rest allDoneBarrier. ...(); try { allDoneBarrier. ...(); } catch (InterruptedException e) {} if (number == monitor.getLargest()) { System.out.printf("Thread #%d won!\n", id); } } }