import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class CountDownExample { private static final int NUM_THREADS = 10; public static void main(String[] args) { CountDownLatch allDoneBarrier = new CountDownLatch(NUM_THREADS); KeepLargest monitor = new KeepLargest(); for (int i = 0; i < NUM_THREADS; i++) { new Thread(new Contender(monitor, allDoneBarrier)).start(); } try { allDoneBarrier.await(); } catch (InterruptedException e) { System.out.println(e); } System.out.println("Largest: " + monitor.getLargest()); } } class KeepLargest { private final Lock lock = new ReentrantLock(); private int largest; public int getLargest() { return largest; } public void giveNumber(int number) { lock.lock(); try { if (number > largest){ largest = number; } } finally { lock.unlock(); } } } class Contender implements Runnable { private KeepLargest monitor; private int id; private CountDownLatch latch; private static int workerNumber = 0; public Contender(KeepLargest monitor, CountDownLatch latch) { this.monitor = monitor; this.latch = latch; this.id = workerNumber++; } @Override public void run() { Random random = new Random(); int number = random.nextInt(100); System.out.printf("Thread #%d generated number: %d\n", id, number); monitor.giveNumber(number); latch.countDown(); try { latch.await(); } catch (InterruptedException e) { System.out.println(e); } if (number == monitor.getLargest()) { System.out.printf("Thread #%d won!\n", id); } } }