在消费达到某种条件时取消订阅是否安全? 退订方式一退订方式2

问题描述

我想在消费时结束订阅队列。

但是我的ack模式是AckNowledgeMode.AUTO,容器会根据监听器是正常返回还是抛出异常来发出ack/nack。

所以,如果我在消耗方法中取消订阅,然后该方法返回,并且容器尝试确认,但它之前已经取消订阅,那么会发生什么,这样做是否安全,如下所示:

退订方式一

        DirectMessageListenerContainer container = getContainer();
        container.setMessageListener(message -> {
            // do something with message

            // if some condition reaches,unsubscribe
            if (reachEnd()) {
                container.removeQueueNames(message.getMessageProperties().getConsumerQueue());
            }
        });

退订方式2

        container.setMessageListener(new ChannelAwareMessageListener() {
            @Override
            public void onMessage(Message message,Channel channel) throws Exception {
                // do something with message

                // if some condition reaches,unsubscribe
                if (reachEnd()) {
                    channel.basicCancel(message.getMessageProperties().getConsumerTag());
                }
            }
        });

解决方法

我两者都不做,而是停止容器。无论哪种方式都会导致消费者被取消。

您应该在新线程上调用 stop(),而不是在侦听器线程上调用 - 这会导致死锁。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...