如何理解JMS中的"同步"和"异步"消息?

Fre*_*ind 16 java asynchronous jms synchronous

阅读JMS的一些文件后,我完全被这句话不解synchronousasynchronouns.

见此页:http://docs.oracle.com/cd/E19798-01/821-1841/bncdq/index.html

同步

您使用receive方法同步使用消息.您可以在调用start方法后随时使用此方法:

connection.start();
Message m = consumer.receive();
connection.start();
Message m = consumer.receive(1000); // time out after a second
Run Code Online (Sandbox Code Playgroud)

要异步使用消息,请使用消息侦听器,如下一节所述.

异步

JMS消息侦听器消息侦听器是一个对象,充当消息的异步事件处理程序.此对象实现MessageListener接口,该接口包含一个onMessage方法.在onMessage方法中,您可以定义消息到达时要执行的操作.

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

Listener myListener = new Listener();
consumer.setMessageListener(myListener);
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

  1. 据我所知,JMS的本质是异步的.生产者将消息发布到队列/主题,它不需要等待消费者.这是异步行为.怎么会"同步"?

  2. 如果"mesageListener"是异步的,但在我使用spring-jms的测试中,我发现它总是在一个线程中运行.这意味着,如果我写Thread.sleep(2000)onMessage,它具有处理下一条消息之前是等待2秒.它是"异步"吗?

JB *_*zet 18

如果您更好地理解它,请consumer.receive()使用模型:您从队列中读取并被阻止等待此消息,直到它出现,或者已经过了一些超时.

使用侦听器使用推送模型:您注册一个侦听器,并在收到消息时,在一个单独的线程中调用侦听器.

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


Dim*_*ele 8

就像我理解的那样:

asynchronous - MessageListener:在侦听队列的服务器上使用它.当消息到达时,立即处理它.服务器继续侦听此队列.

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


小智 5

您正在端到端地查看它:从发布者到消费者。是的,无论同步/异步消费者如何,它都是从发布者到消费者的异步交付。但是,您问题中的同步/异步仅适用于消费者,即从 JMS 代理(例如:ApacheMQ)到消费者。正如其他人指出的那样,同步消费者按顺序从代理中提取消息并等待消息。异步消费者注册一个回调,将消息推送给他们(onMessage)。当这些消息从 JMS 代理异步传递给异步消费者时,异步消费者可以去做其他事情。