Is there a better way to wait for two threads to complete their tasks than using the CountDownLatch?
<p>My requirement is to wait for two threads to complete execution before kickstarting a dependent job.</p>

<p>In order to do this, I am able to create a <code>CountDownLatch</code> and a <code>Waiter</code> <code>Thread</code> which will wait for the <code>CountDownLatch</code> to become zero. One constraint is I cannot use the main thread to wait for the two threads to complete. The main thread continues with other tasks.</p>

<p>This thing does work. However, I get a feel of workaround in this than a solid design. </p>

<p><strong>My questions are the following:</strong></p>

<ol>
<li>What are obvious flaws in the current approach? eg spurious signal </li>
<li>What design would you recommend?</li>
</ol>

<p>My current code:</p>

<pre><code>class Waiter implements Runnable {
    private CountDownLatch latch; 

    Waiter (CountDownLatch latch){
        this.latch = latch;
    }

    @Override
    public void run() {
        System.out.println("Waiter Started running..." + latch.getCount());

        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Waiter ready to trigger Next Job!");
    }
}

class Processor implements Runnable {
    private CountDownLatch latch; 

    Processor (CountDownLatch latch){
        this.latch = latch;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        latch.countDown();
    }
}

public class CountDownLatchDemo {
    public static void main (String[] args) throws InterruptedException{
        CountDownLatch latch = new CountDownLatch(2);

        ExecutorService executor = Executors.newFixedThreadPool(2);
        for (int i=0; i&lt; 2; i++){
            executor.submit(new Processor(latch));
        }

        ExecutorService waitExecutor = Executors.newFixedThreadPool(2);
        waitExecutor.submit(new Waiter(latch));

        Thread.sleep(3000);
        executor.shutdown();
        waitExecutor.shutdown();
        System.out.println("Keep doing other things! Sleep here is just for help you run this code for test!");
    }
}
</code></pre>