CountDownLatch分析

Posted 大佛拈花-GoSaint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CountDownLatch分析相关的知识,希望对你有一定的参考价值。

 

 

  1 什么是CountDownLatch呢?

  先看看官网的定义 :一种同步帮助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。

  现在由我来解释什么是CountDownLatch吧;比如说我当前存在4个线程,其中一个是主线程,3个普通线程。我们要做一个项目,希望线程A负责自动登陆,线程B负责记录登陆日志,线程C负责加载页面信息;而我的主线程则只需要在三者完成后才启动,执行其他的应用;

CountDownLatch(int count) 构造一个用给定计数初始化的 CountDownLatch。

  这是CountDownLatch的构造器,count为当前线程的数量,比如上述我们可以传入一个4;

public void await()throws InterruptedException
public boolean await(long timeout,TimeUnit unit) throws InterruptedException
public void countDown()

 await()方法有两个,其中一个指定了超时时间。调用此方法的线程会被挂起,而调用countDown()方法的线程,每一次的调用都会使得之前构造器中的count的值减去1;知道为0时,调用过await()方法的线程会被唤醒,开始执行。

  请看如下的代码:

package com.net;

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

public class CountDownLatchDemo {

    // 1 创建CountDownLatch对象
    private CountDownLatch cdl = new CountDownLatch(2);
    // 1.1 生成随机数对象
    private Random rnd = new Random();

    // 2 第一个线程对象
    class FirstTask implements Runnable {
        private String id;

        public FirstTask(String id) {
            this.id = id;
        }

        @Override
        public void run() {
            System.out.println("Thread " + id + "  is start");
            try {
                // 休眠几秒
                Thread.sleep(rnd.nextInt(1000));
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("Thread  " + id + "  is over");
            // 线程执行完毕调用一次countDown()方法
            cdl.countDown();

        }
    }

    // 3 第二个线程对象
    class SecondTask implements Runnable {
        private String id;

        public SecondTask(String id) {
            this.id = id;
        }

        @Override
        public void run() {
            try {
                // 调用await()方法,使得当前线程挂起
                cdl.await();
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
            //当当前线程被唤醒之后才开始执行
            System.out.println("----------Thread  " + id + "  is start");
            try {
                Thread.sleep(rnd.nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("----------Thread " + id + " is over");
        }

    }
    public static void main(String[] args) {
            // 创建一个线程池
            ExecutorService es = Executors.newCachedThreadPool();
            CountDownLatchDemo cdld = new CountDownLatchDemo();
            //将c,d交给任务2,说明会被率先挂起
            es.submit(cdld.new SecondTask("c"));
            es.submit(cdld.new SecondTask("d"));
            //将a,b交给任务1开始执行
            es.submit(cdld.new FirstTask("a"));
            es.submit(cdld.new FirstTask("b"));
            es.shutdown();
    }
}

 

 

以上是关于CountDownLatch分析的主要内容,如果未能解决你的问题,请参考以下文章

JDKJDK源码分析-CountDownLatch

多线程等待所有子线程执行完使用总结——CountDownLatch使用和源码初步分析

CountDownLatch源码分析

CountDownLatch源码分析

源码分析-CountDownLatch

我该如何做模态对话框片段(代码在我关闭之前不会执行)