Sunday, June 19, 2011

Latches

http://ydtech.blogspot.com/2010/06/countdownlatch-by-example.html

A latch is a boolean condition that is set at most once, ever. Once a single release is issued, all acquires will pass.

Latch is switch or gate
In concurrent programming, a latch is a type of "switch" or "gate". The latch is set up with a particular count value. The count is then counted down, and at strategic moments, a thread or threads waits for the countdown to reach zero before continuing to perform some process. Note that this is a one-off process: once the latch reaches zero, there is no way to reset the count.

So threads can then either count down on the latch or wait for it to reach 0. When the latch reaches 0, all waiting threads are released.

The CountDownLatch class allows one to prevent a set of threads from running until you are ready for them to. For example, you might want to create the threads and then do some initialization tasks before starting them all simultaneously.

CountDownLatch’s constructor takes an integer as a parameter which decides its behavior. Calling await() holds execution till countdownLatch’s count(constructor parameter) become zero and countdown() reduces the count on every call. So calling await() blocks the thread until the count reaches zero.  

Example

package com.vaani.countdown;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchDemo {

public static void main(String[] args) throws Exception {
int nThreads = 3;
final CountDownLatch startLatch = new CountDownLatch(nThreads);
final CountDownLatch endLatch = new CountDownLatch(nThreads);

ExecutorService svc = Executors.newFixedThreadPool(nThreads);
for (int i = 0; i < nThreads; i++) {
svc.execute(new Runnable() {
public void run() {
try {
log("At run()");
startLatch.countDown();
startLatch.await();

log("Do work");
Thread.sleep((int) (Math.random() * 1000));

log("Wait for end");
endLatch.countDown();
endLatch.await();

log("Done");
} catch (Exception e) {
e.printStackTrace();
}
}
});
Thread.sleep(100);
}
}

private static void log(String msg) {
System.out.println(System.currentTimeMillis() + ": "
+ Thread.currentThread().getId() + " " + msg);
}
}

In this code, you’ll see two latches get initialized. Each thread that starts up counts down on the latch and awaits the latch counting down to 0 (when all threads have been initialized). Similarly, each thread waits for all threads to complete at the same time.

Sample output of this program is:

1308458964186: 8 At run()
1308458964286: 9 At run()
1308458964386: 10 At run()
1308458964386: 8 Do work
1308458964386: 10 Do work
1308458964387: 9 Do work
1308458964952: 8 Wait for end
1308458965037: 9 Wait for end
1308458965277: 10 Wait for end
1308458965277: 9 Done
1308458965277: 8 Done
1308458965277: 10 Done


You can see that each thread hits run() at different times, but proceeds past the barrier at the same time. They each then do some random amount of work and wait for the latch, then proceed past it together.

In the example above, each thread waits forever for the latch to trigger. You can also choose to wait for a specified time period before giving up. And you can check the latch to see how many threads have arrived and are now waiting. Each CountDownLatch instance can only be used once and is then dead.

Download the source


You can download the source code of the above program from here.

No comments:

Post a Comment

Chitika