• 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

  • 相关阅读:
    Solaris 10 10/09发布
    MySQL数据库下损坏数据的恢复操作其过程总结
    [.net自定义控件]ComboBox控件重写 之ComboBoxEx
    Qt之正则表达式 QRegExp
    JavaScript中的JSON
    visual studio2008 OpenGL开发配置
    在母版页中使用UpdatePanel
    ASHX中使用Session
    ASP.NET(c#)实现中英文域名查询
    主打小巧快速Puppy Linux 4.3.1正式版发布
  • 原文地址:https://www.cnblogs.com/softidea/p/4982616.html
Copyright © 2020-2023  润新知