Dowemo
0 0 0 0


Question:

Can someone help me to understand what Java CountDownLatch is and when to use it?

I don't have a very clear idea of how this program works. As I understand all three threads start at once and each Thread will call CountDownLatch after 3000ms. So count down will decrement one by one. After latch becomes zero the program prints "Completed". Maybe the way I understood is incorrect.

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Processor implements Runnable {
    private CountDownLatch latch;
    public Processor(CountDownLatch latch) {
        this.latch = latch;
    }
    public void run() {
        System.out.println("Started.");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        latch.countDown();
    }
}

// -----------------------------------------------------

public class App {
    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(3); // coundown from 3 to 0
        ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool
        for(int i=0; i < 3; i++) {
            executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
        }
        try {
            latch.await();  // wait until latch counted down to 0
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Completed.");
    }
}

Best Answer:


NikolaB explained it very well, However example would be helpful to understand, So here is one simple example...

 import java.util.concurrent.*;
  public class CountDownLatchExample {
  public static class ProcessThread implements Runnable {
    CountDownLatch latch;
    long workDuration;
    String name;
    public ProcessThread(String name, CountDownLatch latch, long duration){
        this.name= name;
        this.latch = latch;
        this.workDuration = duration;
    }
    public void run() {
        try {
            System.out.println(name +" Processing Something for "+ workDuration/1000 + " Seconds");
            Thread.sleep(workDuration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+ "completed its works");
        //when task finished.. count down the latch count...
        // basically this is same as calling lock object notify(), and object here is latch
        latch.countDown();
    }
}
public static void main(String[] args) {
    // Parent thread creating a latch object
    CountDownLatch latch = new CountDownLatch(3);
    new Thread(new ProcessThread("Worker1",latch, 2000)).start(); // time in millis.. 2 secs
    new Thread(new ProcessThread("Worker2",latch, 6000)).start();//6 secs
    new Thread(new ProcessThread("Worker3",latch, 4000)).start();//4 secs
    System.out.println("waiting for Children processes to complete....");
    try {
        //current thread will get notified if all chidren's are done 
        // and thread will resume from wait() mode.
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("All Process Completed....");
    System.out.println("Parent Thread Resuming work....");
     }
  }



Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs