您的位置:首页 > 产品设计 > UI/UE

进阶篇:等待多个子线程完毕再执行主线程的方法之CountDownLatch(十二)

2017-04-12 22:30 253 查看
想一想, 有一天你想测试某个方法的性能,你可能会这么去做,你先开启多个线程,然后记录下多个线程的执行总时间,当多个线程全部执行完毕时,回到主线程将时间打印出来...问题在于,你怎么来控制主线程要在全部子线程执行完毕之后再执行呢? 你可能会想到 变量计数...主线程等待轮询... 

Ok,不兜圈子了,JDK的CountDownLatch类简直就是为解决这种问题而生的,我们先来看一下java的API对该类的定义:

CountDownLatch:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

//一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待
//简单的来讲,它就是用来计数的,先标明要等待多少个子任务完成,
//每个子任务完成就将计数减一,直到值变为0,它将不再阻塞,允许主任务往下执行
public static void countDownLatch(){
final CountDownLatch cdl = new CountDownLatch(10);
ExecutorService exec = Executors.newCachedThreadPool();
//假设这是一个主任务
exec.execute(new Runnable() {
public void run() {
try {
//在它的技术变为0之前,cdl.await()方法会导致当前线程一直阻塞
System.out.println("需要等待"+cdl.getCount()+"个子任务完成!");
cdl.await();
System.out.println("主线程允许执行,任务完成!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});

//开启多个子任务,每完成一个任务,调用cdl.countDown()将计数减一,当计数变为0时,被阻塞的主任务将得到执行;
for (int i = 1; i < 11; i++) {
final int count = i;
exec.execute(new Runnable() {
@Override
public void run() {
System.out.println("第"+count+"个任务已经完成");
cdl.countDown();
}
});
}
exec.shutdown();
}


相信看完代码你已经完全明白它的用法了!

可以看到,我们先构建了一个CountDownLatch,注意,它传了一个构造参数 10 ,什么作用呢?这个10 就是它内部使用的一个计数器,当10被递减为0时,它将不再阻塞,而它之所以会阻塞,是因为我们调用了它的await()方法,我们可以调用它的countDown()方法,使得计数减一;

输出*******************************************************************************************

需要等待10个子任务完成!

第1个任务已经完成

第5个任务已经完成

第2个任务已经完成

第7个任务已经完成

第8个任务已经完成

第6个任务已经完成

第3个任务已经完成

第4个任务已经完成

第9个任务已经完成

第10个任务已经完成

主线程允许执行,任务完成!

***********************************************************************************************
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息