介绍
CountDownLatch 是Concurrent包中的一个辅助类,可以把他看成是一个计数器,其内部维护着一个count计数,只不过这个计数器的操作都是原子操作,同时只能有一个线程去操作这个计数器,CountDownLatch通过构造函数传入一个初始计数值,调用者可以通过调用CountDownLatc对象的cutDown()方法来使计数器减1,如果调用者调用对象上的await()方法,那么调用者就会一直阻塞在这里,直到其他线程调用cutDown()来使计数器值为0,才可以继续执行
应用场景
例如文件下载,3个线程分别去下载文件的1/3段,等3个线程全部工作完毕后由另外一个线程去拼接文件,从而完成工作
代码使用
import com.enjoy.demo.p1.ch1.class1.SleepTools;
import java.util.concurrent.CountDownLatch;
/**
* @Author: BillYu
* @Description:演示CountDownLatch 有5个初始化的线程 6个扣除点
* 扣除完毕以后,主线程和业务线程才能继续自己的工作
*
* 作用:是一个线程等待其他的线程完成工作以后再执行,countDown负责计数器的减一
*
* @Date: Created in 10:51 2019-02-26.
*/
public class UseCountDownLatch {
static CountDownLatch latch = new CountDownLatch(6);
/**
* 初始化线程
*/
private static class InitThread implements Runnable{
@Override
public void run() {
System.out.println("Thread_"+Thread.currentThread().getId()+" ready init work....");
//初始化线程完成工作了,countDown只扣减一次
latch.countDown();
for (int i=0;i<2;i++){
System.out.println("Thread_"+Thread.currentThread().getId()+" ...continue do its work");
}
}
}
/**
* 业务线程
*/
private static class BusiThread implements Runnable{
@Override
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i=0;i<3;i++){
System.out.println("BusiThread_"+Thread.currentThread().getId()+" do business");
}
}
}
public static void main(String[] args) {
//单独的初始化线程,初始化分为2步,需要扣减2次
new Thread(new Runnable() {
@Override
public void run() {
SleepTools.ms(1);
System.out.println("Thread_"+Thread.currentThread().getId()+" ready init work step 1st...");
//每完成一步初始化工作,扣减一次
latch.countDown();
System.out.println("begin step 2nd...");
SleepTools.ms(1);
System.out.println("Thread_"+Thread.currentThread().getId()+" ready init work step 2nd...");
//每完成一步初始化工作,扣减一次
latch.countDown();
}
}).start();
new Thread(new BusiThread()).start();
for (int i =0;i<=3;i++){
Thread thread = new Thread(new InitThread());
thread.start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main work is finished");
}
}
初始化线程调用latch.countDown(),等待全部扣减完毕后 业务线程被唤醒进行业务处理