CountDownLatch

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一定在前面

 

 

这个类在实现 某个线程任务必须在其他线程任务已执行完的情况下执行 时有用

 

你可能感兴趣的:(thread)