例示CountDownLatch的使用

CountDownLatch可用于一个线程等待另外一些线程做了一些事后再做自己的事。做事的线程做完事后报一下数:将一个初数值减1,等这个数值变成0时,等待的线程就可以做自己的事。

用join()也能完成相同的目标。但join()意味着必须等待做事线程终止自己才能动手,CountDownLatch没有这个限制,做事线程再报完数后还可以继续做自己的事。

package player.kent.chen.learn.countdownlatch;

import java.util.concurrent.CountDownLatch;

public class HelloLatch {

    private static class Begger implements Runnable {

        private CountDownLatch latch;

        public Begger(CountDownLatch latch) {
            super();
            this.latch = latch;
        }

        public void run() {
            try {
                System.out.println("我是乞丐,要钱吃饭");
                latch.await();  //等待别人报数完毕
                System.out.println("我是乞丐,钱要够了,现在去买吃的");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

    }

    private static final class Walker implements Runnable {
        private CountDownLatch latch;

        public Walker(CountDownLatch latch) {
            this.latch = latch;
        }

        public void run() {
            takeTime(3000l);
            System.out.println("我是行人" + Thread.currentThread().getName()
                    + "  我走到乞丐跟前花了3秒钟,然后给了乞丐一块钱");
            latch.countDown();  //给完钱后,报数

            takeTime(10000l);  //报完数后,继续做自己的事,线程仍然活着
            System.out.println("我是行人" + Thread.currentThread().getName()
                    + "  给完钱后,我在无边的人海中继续前行直到永远。。。");
            takeTime(Long.MAX_VALUE);
        }

        private void takeTime(long time) {
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {

            }
        }

    }

    public static void main(String[] args) throws InterruptedException {
        int count = 3;
        CountDownLatch latch = new CountDownLatch(count);
        new Thread(new Begger(latch)).start();

        Thread.sleep(3000);

        Thread[] threads = new Thread[count];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Walker(latch));
            threads[i].setName("walker" + i);
        }

        for (Thread thread : threads) {
            thread.start();
            System.out.println(thread.getName() + " 已经动身了 ");
            Thread.sleep(1000l); //动身时间间隔一秒
        }

    }

}

执行结果:

我是乞丐,要钱吃饭

walker0 已经动身了

walker1 已经动身了

walker2 已经动身了

我是行人walker0  我走到乞丐跟前花了3秒钟,然后给了乞丐一块钱

我是行人walker1  我走到乞丐跟前花了3秒钟,然后给了乞丐一块钱

我是行人walker2  我走到乞丐跟前花了3秒钟,然后给了乞丐一块钱

我是乞丐,钱要够了,现在去买吃的

我是行人walker0  给完钱后,我在无边的人海中继续前行直到永远。。。

我是行人walker1  给完钱后,我在无边的人海中继续前行直到永远。。。

我是行人walker2  给完钱后,我在无边的人海中继续前行直到永远。。。

同时各行人线程仍处于alive状态。

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.