七、多线程之CountDownLatch

CountDownLatch

一个线程需要等到其他线程进行某操作时,可以使用CountDownLatch。 CountDownLatch构造方法,带有一个int类型的参数。

public CountDownLatch(int count) 

当一个线程调用countDownLatch.await()时,线程会等待。直到其他线程执行 countDownLatch.countDown()。每执行一个countDown方法,初始化的count会减一,直到count=0时,等待线程才被唤醒。

假设场景顾客餐厅吃饭,需要等待做饭,炒菜,上汤都完成了,才开始吃饭。 代码:

//顾客线程
public class Customer implements  Runnable {

    private final CountDownLatch countDownLatch;

    public Customer(CountDownLatch countDownLatch){
        this.countDownLatch=countDownLatch;
    }
    public void run() {
        System.out.println("点完菜,等待开吃");
        try {
            this.countDownLatch.await();
            System.out.println("开饭了。。。。。。。。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


}

public  static  void main(String[] args) throws InterruptedException {
        final CountDownLatch countDownLatch = new CountDownLatch(3);

        Thread customer = new Thread(new Customer(countDownLatch));
        //顾客进餐厅点菜
        customer.start();

        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("做饭");
                }finally {
                    countDownLatch.countDown();
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("炒菜");
                }finally {
                    countDownLatch.countDown();
                }
            }
        }.start();
        
        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("上汤");
                }finally {
                    countDownLatch.countDown();
                }
            }
        }.start();

        customer.join();
    }

输出:

点完菜,等待开吃
做饭
炒菜
上汤
开饭了。。。。。。。。

结果正确,等待做饭,炒菜,上汤都完成了,才开始吃饭。

总结:

  1. countDownLatch内部通过共享锁实现
  2. countDown方法最好放在finally代码块中执行,防止线程永远等待
  3. CountDownLatch再 count减到0之后,再次执行countDown不会有影响,count不变。
  4. await方法有重载方法 public boolean await(long timeout, TimeUnit unit),等待一段时间后恢复。
  5. countDownLatch只能使用一次,count=0时,不能回滚再次使用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章