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

来源:互联网 发布:unity3d圣典 编辑:程序博客网 时间:2024/06/07 20:10

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

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() {@Overridepublic 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个任务已经完成
主线程允许执行,任务完成!

***********************************************************************************************



1 0