1 什么是CountDownLatch呢?
先看看官网的定义 :一种同步帮助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
现在由我来解释什么是CountDownLatch吧;比如说我当前存在4个线程,其中一个是主线程,3个普通线程。我们要做一个项目,希望线程A负责自动登陆,线程B负责记录登陆日志,线程C负责加载页面信息;而我的主线程则只需要在三者完成后才启动,执行其他的应用;
CountDownLatch(int count) 构造一个用给定计数初始化的 CountDownLatch。
这是CountDownLatch的构造器,count为当前线程的数量,比如上述我们可以传入一个4;
public void await()throws InterruptedExceptionpublic boolean await(long timeout,TimeUnit unit) throws InterruptedExceptionpublic 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(); }}