Suggested Pages

Saturday, February 28, 2015

Java Concurrent - CountDownLatch

In this post we are going to see an example of usage of the class CountDownLatch. A tipical scenario in which it may be useful to use CounDownLatch, is the that shown below.

Example

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;


/**
 * The Class Example.
 */
public class Example {

 /**
  * The main method.
  * 
  * @param args
  *            the arguments
  */
 public static void main(String[] args) {

  Race race = new Race(2);
  race.start();
 }

 /**
  * The Class Runner.
  */
 static class Runner {

  /** The count down latch. */
  private CountDownLatch countDownLatch;

  /**
   * Instantiates a new runner.
   * 
   * @param countDownLatch
   *            the count down latch
   */
  public Runner(CountDownLatch countDownLatch) {
   this.countDownLatch = countDownLatch;
  }

  /**
   * Go.
   */
  public void go() {
   new Thread() {
    public void run() {
     try {
      System.out.println("Running..." + Thread.currentThread().getName());
      Thread.sleep((long) (Math.random() * 10));
     } catch (InterruptedException e) {
     }
     countDownLatch.countDown();
     System.out.println("End of running " + Thread.currentThread().getName());
    };
   }.start();
  }
 }

 
 /**
  * The Class Race.
  */
 static class Race {
  
  /** The count down latch. */
  private CountDownLatch countDownLatch;
  
  /** The runners. */
  private List<Runner> runners = new ArrayList<Runner>();

  
  
  /**
   * Instantiates a new race.
   *
   * @param numOfPartecipans the num of partecipans
   */
  public Race(int numOfPartecipans) {
   countDownLatch = new CountDownLatch(numOfPartecipans);
   for (int i = 0; i < numOfPartecipans; i++) {
    runners.add(new Runner(countDownLatch));
   }
  }

  /**
   * Start.
   */
  public void start() {
   for (Runner runner : runners) {
    runner.go();
   }
   waitOnFinishLine();
  }

  /**
   * Wait on finish line.
   */
  private void waitOnFinishLine() {
   try {
    countDownLatch.await();
   } catch (InterruptedException e) {
   }
   System.out.println("Race ended");
  }

  
  /**
   * Gets the runners.
   *
   * @return the runners
   */
  List<Runner> getRunners() {
   return runners;
  }

 }

}


Suppose that you have a race with some partecipants and you have to print the result of the race at the exact moment when the last runner arrives at the finishing line.
CountDownLatch allows you to synchronized the two involved thread types: - The thread that is responsible of waiting for the termination of the race. - The threads that design each partecipant to the race.
CountDownLatch is initialized with an integer that describes the number of runners in the race. As you can see each "Runner object" makes use of a "Thread ", that makes use of the method CountDownLatch#countDown() , while the "Race object" ( that runs in the main thread) uses the method CountDownLatch#await().
The main thread is blocked on the method CountDownLatch#await(). until the last Runner completes the run and invokes the method CountDownLatch#countDown().
This example is very easy and shows how to use CountDownLatch in order to allow a thread (generally a Consumer Thread) to expect that other threads (generally Producer Thread) perform particular operation.
In a wider consideration, the totality of the Runner threads represents the real Producer.

Suggested Pages