原文:http://blog.csdn.net/junshuaizhang/article/details/39580751
package com.imooc;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* CountDownLatch的应用场景:
* 有一个任务A想要往下执行,但必须要等到其他的任务(B,C,D,E,F...)执行完毕后才可以继续往下执行.
*
* 假如任务A调用CountDownLatch对象的await方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象
* 上的countDown()方法,这个调用await方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止
*
* CountDownLatch类有3个基本元素:
* 1.初始值决定CountDownLatch需要等待的线程的数量;
* 2.await方法,被等待全部线程终结的线程调用
* 3.countDown方法,线程主要任务执行完,调用
*
* 基本原理:当创建CountDownLatchj对象时,对象使用构造函数的参数来初始化内部计数器,每次调用countDown方法,CountDownLatch
* 对象内部计数器减一;当内部计数器达到0时,CountDownLatch对象唤醒全部使用await方法睡眠的线程们.
*
*/
public class CountDownLatchTest {
public static void main(String[] args) {
Commanders commanders = new Commanders(9);//初始化参数为要等待的线程数;
Thread waitThread = new Thread(commanders);
waitThread.start();
for (int i = 0; i < 10; i++) {
ProWorkers proWorker = new ProWorkers(commanders,"小线程" + i);
Thread temp = new Thread(proWorker);
temp.start();
}
}
}
/**
* 等待执行的任务
*/
class Commanders implements Runnable {
private final CountDownLatch controller;
public Commanders(int num) {
this.controller = new CountDownLatch(num);
}
public void arrive(String name) {
System.out.println(name + " has arrived");
System.out.println("Commanders: waiting for " + controller.getCount());
controller.countDown();//线程没执行一次,计数器减少一次
}
@Override
public void run() {
System.out.println("Commanders: initialization " + controller.getCount());
try {
controller.await();
System.out.println("Commanders: running ->>> ending");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 优先执行的任务
*/
class ProWorkers implements Runnable {
private Commanders commanders;
private String name;
public ProWorkers(Commanders commanders, String name) {
this.commanders = commanders;
this.name = name;
}
@Override
public void run() {
long duration = (long)(Math.random()*10);
try {
TimeUnit.SECONDS.sleep(duration);//将long类型转为秒,内部其实执行Thread.sleep方法
} catch (InterruptedException e) {
e.printStackTrace();
}
commanders.arrive(name);
}
}