Java - CountDownLatch

[Updated: Jul 30, 2017, Created: Jul 21, 2017]

In Java, a CountDownLatch allows one or more threads to wait until a set of operations being performed in other threads completes.

A CountDownLatch is initialized with a given count.

The method CountDownLatch#countDown() decreases the count by one.

The method CountDownLatch#await() blocks until the underlying count becomes zero.

This can be useful for multiple purposes, for example a number of threads can be paused for other threads to reach to a certain point before progressing.

CountDownLatch is synchronized internally, so it can be used by multiple threads. Also actions in a thread before calling countDown() establish happen-before relation with the actions following a successful return from a corresponding await() in another thread.

Let's understand CountDownLatch with an example.

Example

public class CountDownLatchExample {
  private static final int LATCH_COUNT = 4;

  public static void main(String[] args) {
      CountDownLatch latch = new CountDownLatch(LATCH_COUNT);
      JFrame frame = createFrame();
      frame.setLayout(new FlowLayout(FlowLayout.LEFT));

      for (int i = 1; i <= LATCH_COUNT; i++) {
          ProgressThread progressThread = new ProgressThread(latch, i * 10);
          frame.add(progressThread.getProgressComponent());
          progressThread.start();
      }

      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
  }

  private static JFrame createFrame() {
      try {
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {
          e.printStackTrace();
      }
      JFrame frame = new JFrame("CountDownLatch Example");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(new Dimension(ProgressThread.PROGRESS_WIDTH, 170));
      return frame;
  }

}
public class ProgressThread extends Thread {
  public static final int PROGRESS_WIDTH = 350;
  private static final int CATCH_UP_COUNT = 75;
  private final JProgressBar progressBar;
  private final CountDownLatch latch;
  private final int slowness;

  public ProgressThread(CountDownLatch latch, int slowness) {
      this.latch = latch;
      this.slowness = slowness;
      progressBar = new JProgressBar();
      progressBar.setPreferredSize(
              new Dimension(PROGRESS_WIDTH - 30, 25));
      progressBar.setStringPainted(true);
  }

  JComponent getProgressComponent() {
      return progressBar;
  }

  @Override
  public void run() {

      int c = 0;
      while (true) {
          progressBar.setValue(++c);
          if (c > 100) {
              break;
          }

          try {
              Thread.sleep(c < CATCH_UP_COUNT ? slowness : 100);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }

          if (c == CATCH_UP_COUNT) {
              //decrease the count
              latch.countDown();
              try {
                  //wait until count = 0
                  latch.await();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
  }
}

Output

As seen in the output, all four threads wait at 75% for the CountDownLatch to reach a value of zero (from initial value of 4) before progressing further.

The CountDownLatch logic from above example can be used with some useful multiple tasks which want to submit their individual work at the catch-up point.

Example Project

Dependencies and Technologies Used :

  • JDK 1.8
  • Maven 3.3.9

CountDownLatch Example Select All Download
  • count-down-latch-example
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also