该lazyListen()
方法将listening
标志设置为 true,然后启动一个线程来运行 SubscriptionTask。然后调用addMessageListener()
相同的 JedisConnection 来订阅更多主题。但是 SubscriptionTask 启动过程没有保护,调用addMessageListener()
可能在该过程完成之前到达,因此订阅可能完全丢失,或者两个线程可能同时写入同一个输出流,因此 Redis 被发送一个损坏的命令。
在取消订阅所有主题后关闭任务时会出现类似的问题。在连接返回池之前,可能会在连接上发送新的订阅命令。如果该连接随后用于非订阅命令,则会发生错误。
可以通过订阅主题并等待订阅任务完全建立后再允许进一步的连接来缓解该问题,并且永远不要取消订阅。但是即使这样,如果因为抛出异常而关闭任务,仍然可能会发生这种情况,因此下次订阅主题时会创建一个新的 SubscriptionTask。