title: Is there a better way to wait for two threads to complete their tasks than using the CountDownLatch?
body: <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>