Java高并发编程之CountDownLatch

上一篇文章解决了这个面试题:实现一个容器,提供两个方法,add和size。写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5时,线程2给出提示并结束。
采用synchronized、wait和notify相结合的方式,详见:Java高并发编程之synchronized与wait和notify结合
尽管这是挺好的解决办法,当绝对谈不上最佳,本篇文章进一步讲解更优的解决方案。
使用latch(门闩)替代wait、notify来进行通知,其好处是通信方式简单,同时也可以指定等待时间。
CountDownLatch不涉及锁定,当count的值为零的时候当前线程继续运行。
当不涉及同步,只是涉及线程通信的时候,用synchronized + wait/notify显得太重了,这是应用考虑CountDownLatch。
代码如下:

public class MyContainer3 {
    private List<Integer> lists = new ArrayList<>();
    public void add(Integer a) {
        lists.add(a);
    }
    public Integer size() {
        return lists.size();
    }

    public static void main(String[] args) {
        MyContainer3 c = new MyContainer3();
        CountDownLatch countDownLatch = new CountDownLatch(1);

        new Thread(()->{
            System.out.println("thread 1 start...");
            if(c.size() != 5) {
                try {
                    countDownLatch.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println("thread 2 end.");
        }, "t2").start();
        
        new Thread(()->{
            try {
                for(int i = 0; i < 10; i++) {
                    c.add(i);
                    if(c.size() == 5) {
                        countDownLatch.countDown();
                    }
                    Thread.sleep(1000);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "t1").start();
    }
}

在上面代码中,t2线程先启动,判断容器size不为5的时候,调用countDownLatch的await,开始等待;t1线程启动后,for循环每秒往容器中添加一个元素,当容器中元素个数为5的时候,调用countDownLatch的countDown方法,此时count值减为0,t1线程继续执行,而t2线程不受影响。这个过程中,没有加锁,也没有释放锁,通信过程非常简单。

猜你喜欢

转载自blog.csdn.net/weixin_42486373/article/details/83963193