2014-02-28 109 views
12

在阅读了JMS的一些文档后,我完全被synchronousasynchronouns这个短语所困惑。如何理解JMS中的“同步”和“异步”消息传递?

看到这个页面:http://docs.oracle.com/cd/E19798-01/821-1841/bncdq/index.html

同步

您使用接收方法同步的方式使用的消息。 你可以随时使用这个方法调用start方法后:

connection.start(); 
Message m = consumer.receive(); 
connection.start(); 
Message m = consumer.receive(1000); // time out after a second 

为了异步消耗消息,您可以使用消息监听器,在下一节描述。

异步

JMS消息监听器 消息侦听器是充当消息的异步事件处理的对象。这个对象实现了MessageListener接口,它包含一个方法onMessage。在onMessage方法中,您定义了消息到达时要采取的操作。

您使用setMessageListener方法向特定的MessageConsumer注册消息侦听器。例如,如果你定义一个类名为监听器实现MessageListener接口,您可以按如下注册消息监听器:

Listener myListener = new Listener(); 
consumer.setMessageListener(myListener); 

我有两个问题:

  1. 至于我的理解,JMS的本质是异步的。生产者将消息发布到队列/主题,它不需要等待消费者。这是异步行为。它怎么可能是“同步”?

  2. 如果“mesageListener”是异步的,但是在使用spring-jms进行测试时,我发现它总是在一个线程中运行。这意味着,如果我在onMessage中编写Thread.sleep(2000),则必须等待2秒才能处理下一条消息。它是“异步”吗?

回答

12

如果你喜欢这个更好的了解它,consumer.receive()使用模式:从队列中读取,并阻塞等待此消息,直到它,或者一些超时时间。

使用监听器使用推送模型:您注册一个监听器,并且当消息进入时,监听器被调用,在一个单独的线程中。

一切都在Java中的一个线程中完成,并且侦听器调用也不例外。侦听器消息处理是否阻止处理队列中的其他消息取决于有多少线程专用于消息处理。如果将Spring配置为使用5个线程池异步处理消息,则5个侦听器将能够并行处理消息。

+0

感谢您的“拉”和“推”解释! – Freewind

5

就像我明白这一点:

异步 - 消息监听:使用此侦听队列的服务器上。消息到达时,立即处理。服务器一直在监听这个队列。

synchronous - consumer.receive(1000):在客户端应用程序上使用它,此时需要检查消息是否打算供此客户端使用。例如:每60秒轮询一次。这只能很快打开与服务器的连接。 1000毫秒将保持此连接打开。如果消息在这1000毫秒内到达,则消息被消耗并且连接关闭。

2

您正在关注端到端:从发布商到消费者。是的,它是从发布者到消费者的异步传递,与Sync/Async消费者无关。但是,您的问题中的同步/异步仅适用于消费者,即从JMS代理(例如:ApacheMQ)到消费者。正如其他人指出的,同步消费者从代理人中顺序提取消息并等待消息。异步使用者在消息推送给他们的地方注册回调(onMessage)。异步使用者可以在从JMS代理异步传递这些消息的同时执行其他操作。