美文网首页
通过Spring官方Demo理解CountDownLatch的用

通过Spring官方Demo理解CountDownLatch的用

作者: 菜鸟的成神之旅 | 来源:发表于2018-08-30 15:26 被阅读0次

    今天看spring官方实例代码springboot整合rabbitmq发现有用到CountDownLatch
    首先贴上spring demo

    public class Receiver {
    
        private CountDownLatch latch = new CountDownLatch(1);
    
        public void receiveMessage(String message) {
            System.out.println("Received <" + message + ">");
            latch.countDown();
        }
    
        public CountDownLatch getLatch() {
            return latch;
        }
    
    }
    
    public class Runner implements CommandLineRunner {
    
        private final RabbitTemplate rabbitTemplate;
        private final Receiver receiver;
    
        public Runner(Receiver receiver, RabbitTemplate rabbitTemplate) {
            this.receiver = receiver;
            this.rabbitTemplate = rabbitTemplate;
        }
    
        @Override
        public void run(String... args) throws Exception {
            System.out.println("Sending message...");
            rabbitTemplate.convertAndSend(MqConfig.topicExchangeName, "foo.bar.baz", "Hello from RabbitMQ!");
            receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);
        }
    
    }
    

    在这个demo中除了有参构造new CountDownLatch(1)用到了CountDownLatch的两个方法latch.countDown()receiver.getLatch().await(10000, TimeUnit.MILLISECONDS)

    让我们先看看官方文档https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html

    Modifier and Type Method and Description
    boolean await(long timeout, TimeUnit unit)
    Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted, or the specified waiting time elapses.
    void countDown()
    Decrements the count of the latch, releasing all waiting threads if the count reaches zero.

    看了文档可以知道countDown()每次回会让初始化的计数器减一。await用于阻塞当前线程直到计数器减到0,除非线程被打断或者等待超时。因此我们可以让初始计数为多个,在多个方法中调用countDown()方法,可以用来确保只有多个方法的countDown()方法都执行后。他们才会才会执行接下来的代码。

    不过在spring的这个demo中初始计数器为1,我们尝试注释到Runner中await方法发现发送和消费信息也可以正常的打印,因为只要Receiver中的latch.countDown()执行一次计数器就会减为0当前线程代码就会执行。 那么这里Runner中的await在这里有什么用呢?

    我们再来看看await()这个方法,它阻塞的是当前的线程。也就是会阻塞Runner这个线程,而在我们这个demo中await()方法后并没有后续的代码逻辑,导致我们看不到await()的作用。我们在await()方法后边打印一行日志logger.info("finished")然后分别注释掉await()和不注释执行看下结果:

    //注释掉await()方法
    Sending message...
    finished
    Received <Hello from RabbitMQ!>
    
    //没有注释掉await()方法
    Sending message...
    Received <Hello from RabbitMQ!>
    finished
    

    这下大家就很容易理解CountDownLatch和await()的作用了

    相关文章

      网友评论

          本文标题:通过Spring官方Demo理解CountDownLatch的用

          本文链接:https://www.haomeiwen.com/subject/yzxdwftx.html