CountDownLatch
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。
之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。
这种现象只出现一次——计数无法被重置。(如果CountDownLatch实例是一个对象的字段,这个对象相同的方法非第一次被调用,则无法出现排队等待的情况)
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 1 Thread[pool-1-thread-2,5,main]Initializing component 2 Thread[pool-1-thread-3,5,main]Initializing component 3 Thread[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