CountDownLatch
CountDownLatch是一个可以使其他线程等待某些线程执行完毕后再进行执行的工具类。
用我个人的理解来说的话,就是它提供了一个await()方法来阻塞当前线程,直到countDown()方法使得计数器递减到0之后,对阻塞队列中线程进行唤醒,来达到一种等待的效果。
CountDownLatch的常用方法
CountDownLatch(int count); //构造方法,创建一个值为count 的计数器。
await();//阻塞当前线程,将当前线程加入阻塞队列。
countDown();//对计数器进行递减1操作,当计数器递减至0时,当前线程会去唤醒阻塞队列里的所有线程。
CountDownLatch的使用场景
例如在某些需要加载拼装的报表或者是表格之类的时候,往往是得到所有的数据之后再进行拼装呈现。
如果有ABCDE五个模块,需要等待五个模块都加载完毕后才能进行展示,比较容易想到的就是把这个串行的方式改为并行。
首先设置一个计数器为5的CountDownLatch,再五个子线程中分别执行ABCDE模块的加载或者数据处理,每一个线程执行完毕后,进行countDown()操作,5个线程执行5次countDown()后唤醒了主线程进行拼装展示。
DEMO
package com.LIUYONGZHENG;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
public class Wingzing {
private static volatile Map map=new HashMap();
//创建计数器,计数器为5
private static CountDownLatch countDownLatch=new CountDownLatch(5);
public static void main(String[] args) {
//记录开始时间
long startTime=System.currentTimeMillis();
Thread WingzingThreadA=new Thread(new Runnable() {
public void run() {
try {
System.out.println("正在执行A模块相关操作");
Thread.sleep(5000);//任务执行需要5秒
map.put("A",1);
countDownLatch.countDown();//标记已经完成一个任务
System.out.println("A模块操作完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread WingzingThreadB=new Thread(new Runnable() {
public void run() {
try {
System.out.println("正在执行B模块相关操作");
Thread.sleep(5000);//任务执行需要5秒
map.put("B",1);
countDownLatch.countDown();//标记已经完成一个任务
System.out.println("B模块操作完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread WingzingThreadC=new Thread(new Runnable() {
public void run() {
try {
System.out.println("正在执行C模块相关操作");
Thread.sleep(5000);//任务执行需要5秒
map.put("C",1);
countDownLatch.countDown();//标记已经完成一个任务
System.out.println("C模块操作完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread WingzingThreadD=new Thread(new Runnable() {
public void run() {
try {
System.out.println("正在执行D模块相关操作");
Thread.sleep(5000);//任务执行需要5秒
map.put("D",1);
countDownLatch.countDown();//标记已经完成一个任务
System.out.println("D模块操作完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread WingzingThreadE=new Thread(new Runnable() {
public void run() {
try {
System.out.println("正在执行E模块相关操作");
Thread.sleep(5000);//任务执行需要5秒
map.put("E",1);
countDownLatch.countDown();//标记已经完成一个任务
System.out.println("E模块操作完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//启动子线程执行任务
WingzingThreadA.start();
WingzingThreadB.start();
WingzingThreadC.start();
WingzingThreadD.start();
WingzingThreadE.start();
try {
//主线程进行等待,直到5个子线程执行完毕后进行唤醒
countDownLatch.await();
long endTime=System.currentTimeMillis();
System.out.println("------ABCDE全部完成--------");
System.out.println("结果为:"+map.toString());
System.out.println("任务总执行时间为"+(endTime-startTime)/1000+"秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}