public class Driver2 { // ... public static void main(String[] args) throws InterruptedException { int N = 5; CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(N); for (int i = 0; i < N; ++i) // create and start threads new Thread(new Worker(startSignal, doneSignal)).start(); System.out.println("don't let run yet"); // don't let run yet startSignal.countDown(); // let all threads proceed System.out.println("startSignal.countDown()ed"); doneSignal.await(); // wait for all to finish System.out.println("main down"); } } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { this.startSignal = startSignal; this.doneSignal = doneSignal; } public void run() { try { startSignal.await(); doWork(); doneSignal.countDown(); } catch (InterruptedException ex) { } // return; } void doWork() { System.out.println("doWork"); } }
console
don't let run yet startSignal.countDown()ed doWork doWork doWork doWork doWork main down
外表看 运行机制是
CountDownLatch startSignal = new CountDownLatch(N);
这个对象可以让好几个线程拥有(就是可以操作它),当某个线程执行了 startSignal.await();的时候该线程就会处于等待状态,然后一定要等其他可以操作该startSignal 的线程执行了N次countDown();的时候wait的线程才可以继续执行
startSignal.await();
startSignal .countDown();
下面写了段代码证实
public class CountDownTest extends TestCase { public void test1() throws Exception { final CountDownLatch a = new CountDownLatch(2); (new Thread() { public void run() { try { Thread.sleep(5000); System.out.println("the thread start to run"); a.countDown(); a.countDown(); System.out.println("the thread countdown twice"); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); System.out.println("a thread start, main going to wait"); a.await(); System.out.println("main down"); } }
console
a thread start, main going to wait thread start to run main down one thread countdown twice
初始化了一个2次的CountDownLatch 然后让单个线程中执行2次countdown, 主线程等待结束 输出一句话后结束
子线程 接着也结束 ,但最后2句console的输出顺序是随机的 是线程竞争的结果
改下
System.out.println("a thread start, main going to wait"); a.await(); Thread.sleep(100); System.out.println("main down"); a thread start, main going to wait the thread start to run the thread countdown twice main down 可以看到这次输出结果 就不一样了 因为我强迫主线程sleep 避免了竞争 子线程输出的the thread countdown twice一定在前面
这个类在实现 某个线程任务必须在其他线程任务已执行完的情况下执行 时有用