CountDownLatch是同步工具类之一,可以指定一个计数值,在并发环境下由线程进行减1操作,当计数值变为0之后,被await方法阻塞的线程将会唤醒,实现线程间的同步。主线程启动10个子线程后阻塞在await方法,需要等子线程都执行完毕,主线程才能唤醒继续执行。
测试代码如下:
public static void main(String[] args) throws InterruptedException {
int threadNum = 10;
final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
for (int i = 0; i < threadNum; i++) {
final int finalI = i + 1;
new Thread(new Runnable() {
public void run() {
System.out.println("thread " + finalI + " start");
Random random = new Random();
try {
Thread.sleep(random.nextInt(10000) + 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread " + finalI + " finish");
countDownLatch.countDown();
}
}).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(threadNum + " thread finish");
}
测试结果:
thread 1 start
thread 3 start
thread 4 start
thread 5 start
thread 9 start
thread 7 start
thread 2 start
thread 6 start
thread 8 start
thread 10 start
thread 10 finish
thread 5 finish
thread 8 finish
thread 3 finish
thread 7 finish
thread 9 finish
thread 2 finish
thread 4 finish
thread 6 finish
thread 1 finish
10 thread finish
从上面例子可以看出,启动打印 线程1 启动,执行 countDown方法,等待线程数减1 ,for循环继续跑,线程1 遇到await方法进行等待countDownLatch等待数为0,才会被唤醒,唤醒为随机
关于 CyclicBarrier和CountDownLatch区别
CyclicBarrier和CountDownLatch 都位于java.util.concurrent 这个包下
CountDownLatch | CyclicBarrier |
减计数方式 | 加计数方式 |
计算为0时释放所有等待的线程 | 计数达到指定值时释放所有等待线程 |
计数为0时,无法重置 | 计数达到指定值时,计数置为0重新开始 |
调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 | 调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞 |
不可重复利用 | 可重复利用 |
具体参考 :http://blog.csdn.net/tolcf/article/details/50925145