CountDownLatch是Java1.5之后引入的Java并发工具类。
CountDownLatch能够使一个或多个线程等待其他线程完成各自的工作后再执行。
CountDownLatch是JDK 5+里面闭锁的一个实现。
方法介绍:
//指定计数的次数,只能被设置1次
public CountDownLatch(int count);
//调用此方法则计数减1
public void countDown();
//调用此方法会一直阻塞当前线程,直到计时器的值为0,除非线程被中断。
public void await() throws InterruptedException
//得到当前的计数
Public Long getCount();
//调用此方法会一直阻塞当前线程,直到计时器的值为0,除非线程被中断或者计数器超时,返回false代表计数器超时。
Public boolean await(long timeout, TimeUnit unit)
代码演示中:模拟3个业务线程和主线程等待4个初始化线程和一个执行2次计数器减一的线程结束后在执行,计数器初始值为6。
import java.util.concurrent.CountDownLatch;
/**
* CountDownLatch
* 作用:是一组线程等待其他的线程完成工作以后再执行,加强版join
*/
public class UseCountDownLatch {
//构造函数参数count值大于等于线程数
private static CountDownLatch latch = new CountDownLatch(6);
//初始化线程,本案例中让业务线程等待初始化线程结束再执行
private static class InitThread implements Runnable{
@Override
public void run() {
System.out.println("线程"+Thread.currentThread().getName()+"初始化开始");
for (int i=0;i<10;i++){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程"+Thread.currentThread().getName()+"初始化进行中。。。");
}
System.out.println("线程"+Thread.currentThread().getName()+"初始化结束");
//计数器-1
latch.countDown();
}
}
//业务线程,等待初始化线程结束再执行
private static class BusinessThread implements Runnable{
@Override
public void run() {
try {
//业务线程等待
latch.await();
System.out.println("业务线程"+Thread.currentThread().getName()+"执行中");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
//启动2个业务线程
for (int i=0;i<2;i++){
new Thread(new BusinessThread()).start();
}
//启动1个业务线程,随后中断
Thread businessThread = new Thread(new BusinessThread());
businessThread.start();
businessThread.interrupt();
//启动4个初始化线程
for (int i=0;i<4;i++){
new Thread(new InitThread()).start();
}
//单启一个线程,此处计数器-2
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程"+Thread.currentThread().getId()+"进行了两次计数器-1"+".........");
latch.countDown();
latch.countDown();
}
}).start();
//主线程等待
latch.await();
System.out.println("主线程"+Thread.currentThread().getName()+"执行完毕");
}
}