1、引入CountDownLatch
CountDownLatch是一个非常实用的多线程控制工具类。这个工具类通常用来控制线程等待,它可以让某一个线程等待直到倒计数结束,再开始执行。
对于到计数器,一种典型的场景就是火箭发射。在火箭发射前,为了保证万无一失,往往还要进行各项设备、仪器的检查。只有等待所有的检查完毕后,引擎才能点火。这种场景就非常适合使用CountDownLatch。它可以使得点火线程等待所有检查线程全部完工后,再执行。
CountDownLatch的构造函数接收一个整数作为参数,即当前这个计数器的计数个数。
public CountDownLatch(int count)
2、CountDownLatch的主要逻辑方法
public void await() throws InterruptedException
public boolean await(long timeout, TimeUnit unit) throws InterruptedException
public void countDown()
public long getCount()
- await()方法:让当前线程进行等待,直到的CountDownLatch计数值变为0,或者当前线程被中断。
- await(long timeout, TimeUnit unit)方法:让当前线程进行等待,直到的计数值变为0,或者等待时间用完,或者当前线程被中断。
- countDown()方法:减少CountDownLatch计数值,如果计数达到零则释放所有等待的线程。
- getCount():返回当前CountDownLatch的计数值。
3、简单演示CountDownLatch的使用CountDownLatch
演示代码如下:
public class CountDownLatchDemo implements Runnable
{
static final CountDownLatch end = new CountDownLatch(10);
static final CountDownLatchDemo demo = new CountDownLatchDemo();
@Override
public void run()
{
try
{
//模拟检查任务
Thread.sleep(new Random().nextInt(10) * 1000);
System.out.println("check complete");
//通知CountDownLatch一个线程已经完成了任务。倒计数器可以减1了
end.countDown();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException
{
ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; ++i)
{
exec.submit(demo);
}
//等待检查,要求主线程等待所有检查任务全部完成
end.await();
//发射火箭
System.out.println("Fire");
exec.shutdown();
}
}
上述代码中生成一个CountDownLatch实例,计数数量为10.这表示需要有10个线程完成任务,等待在CountDownLatch上的线程才能继续执行。其中 end.countDown()调用CountDownLatch的countdown()方法,也就是通知CountDownLatch,一个线程已经完成任务,倒计数器可以减1了。其中 end.await()调用CountDownLatch的await()方法,要求主线程等待所有10个检查任务全部完成。待10个任务全部完成后,主线程才能继续执行。
总的来说就是主线程在CountDownLatch上等待,当所有检查任务全部完成后,主线程方能继续执行。