CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞程序继续执行。CountDownLatch可以看作是一个倒计数的锁存器,当计数减至0时触发特定的事件。利用这种特性,可以让主线程等待子线程的结束。
CountDownLatch的一个非常典型的应用场景是:
有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。
package thread.cyclic;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;/** * CountDownLatch是个计数器,它有一个初始数, 等待这个计数器的线程必须等到计数器倒数到零时才可继续。 */public class CountDownLatchTest { /** * 初始化组件的线程 */ public static class ComponentThread implements Runnable { // 计数器 CountDownLatch latch; // 组件ID int id; // 构造方法 public ComponentThread(CountDownLatch latch, int id) { this.latch = latch; this.id = id; } public void run() { // 初始化组件 System.out.println(Thread.currentThread() + "Initializing component " + id); try { TimeUnit.SECONDS.sleep(id); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "Component " + id + " initialized!"); // 将计数器减一 latch.countDown(); } } /** * 启动服务器 */ public static void startServer() throws Exception { System.out.println(Thread.currentThread() + "Server is starting."); // 初始化一个初始值为3的CountDownLatch CountDownLatch latch = new CountDownLatch(3); // 起3个线程分别去启动3个组件 ExecutorService service = Executors.newCachedThreadPool(); service.submit(new ComponentThread(latch, 1)); service.submit(new ComponentThread(latch, 2)); service.submit(new ComponentThread(latch, 3)); service.shutdown(); // 等待3个组件的初始化工作都完成 latch.await(); // 当所需的三个组件都完成时,Server就可继续了 System.out.println(Thread.currentThread() + "Server is up!"); } public static void main(String[] args) throws Exception { CountDownLatchTest.startServer(); }}
Output:
Thread[main,5,main]Server is starting.Thread[pool-1-thread-1,5,main]Initializing component 1Thread[pool-1-thread-2,5,main]Initializing component 2Thread[pool-1-thread-3,5,main]Initializing component 3Thread[pool-1-thread-1,5,main]Component 1 initialized!Thread[pool-1-thread-2,5,main]Component 2 initialized!Thread[pool-1-thread-3,5,main]Component 3 initialized!Thread[main,5,main]Server is up!
http://blog.csdn.net/huang_xw/article/details/7090146
http://www.iteye.com/topic/657295