2015年4月28日
1个发布者,1个订阅者,topic
方式1:
先发布消息:


然后订阅消息:

方式2:
先订阅消息:

然后发布消息:

订阅者如下:
结论1:
方式1:

然后发布消息:

订阅者如下:

结论1:
从上面可以看出,消息发布需要在线发布。
1个发布者,2个订阅者,topic
方式1:
先发布消息:

然后开启两个订阅者


方式2:
先开启两个订阅者:


然后发布消息:

看到订阅者如下:


方式3:
先发布消息,发布完消息后,让发布者休眠10s,然后退出:

此时开启订阅者:

直到发布者程序退出:

订阅者也没有订阅到任何消息

方式4:

上图中,消息1发布完成后,打开订阅者1和订阅者2,紧接着发布者又发布消息2;
在发布者发送消息3之前,订阅者1和订阅者2运行结束。


结论:
1. 在线发布消息:
订阅者能订阅到消息的条件是:
1.1 订阅者程序先运行,即在发布者程序发布消息时,订阅者程序处于运行状态(在线状态);
1.2 由方式3可以看到,发布者程序处于运行状态,并不代表发布者程序处于发布消息状态;
2. 发布者发布的消息,可以被所有订阅者订阅,且所有订阅者不存在竞争关系。

参考程序:需要略作修改,以实现上面提到的方式1.方式2....
订阅者程序:2015年4月28日 9:57:40
package com.ll.activemq;import java.util.Collection;import java.util.Iterator;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.Destination;import javax.jms.MapMessage;import javax.jms.MessageConsumer;import javax.jms.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnection;import org.apache.activemq.ActiveMQConnectionFactory;public class Receiver {public static void main(String[] args) {// ConnectionFactory :连接工厂,JMS 用它创建连接ConnectionFactory connectionFactory;// Connection :JMS 客户端到JMS Provider 的连接Connection connection = null;// Session: 一个发送或接收消息的线程Session session;// Destination :消息的目的地;消息发送给谁.Destination destination;// 消费者,消息接收者MessageConsumer consumer;connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");try {// 构造从工厂得到连接对象connection = connectionFactory.createConnection();// 启动connection.start();// 获取操作连接session = connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);// 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置destination = session.createTopic("FirstTop");consumer = session.createConsumer(destination);// consumer2 = session.createConsumer(destination);System.out.println("订阅者1:消费者程序开始运行...");while (true) {// 设置接收者接收消息的时间,为了便于测试,这里谁定为100sTextMessage message = (TextMessage) consumer.receive(8000);// Object message = (Object) consumer.receive(28000);if (null != message) {System.out.println("订阅者1:收到消息-->" + message.getText());} else {System.out.println("订阅者1:运行结束... ");break;}}} catch (Exception e) {e.printStackTrace();} finally {try {if (null != connection)connection.close();} catch (Throwable ignore) {}}}}
发布者程序:
package com.ll.activemq;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.DeliveryMode;import javax.jms.Destination;import javax.jms.MessageProducer;import javax.jms.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnection;import org.apache.activemq.ActiveMQConnectionFactory;public class Sender {private static final int SEND_NUMBER = 5;public static void main(String[] args) {// ConnectionFactory :连接工厂,JMS 用它创建连接ConnectionFactory connectionFactory;// Connection :JMS 客户端到JMS Provider 的连接Connection connection = null;// Session: 一个发送或接收消息的线程Session session;// Destination :消息的目的地;消息发送给谁.Destination destination;// MessageProducer:消息发送者MessageProducer producer;// TextMessage message;// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jarconnectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");try {// 构造从工厂得到连接对象connection = connectionFactory.createConnection();// 启动connection.start();// 获取操作连接session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);// 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置destination = session.createTopic("FirstTop");// 得到消息生成者【发送者】producer = session.createProducer(destination);// 设置不持久化,此处学习,实际根据项目决定producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);// 构造消息,此处写死,项目就是参数,或者方法获取sendMessage(session, producer);// session.commit();System.out.println("发布者程序退出...");} catch (Exception e) {e.printStackTrace();} finally {try {if (null != connection)connection.close();} catch (Throwable ignore) {}}}public static void sendMessage(Session session, MessageProducer producer)throws Exception {for (int i = 1; i <= SEND_NUMBER; i++) {TextMessage message = session.createTextMessage("ActiveMq 发布的消息"+ i);// 发送消息到目的地方System.out.println("发布消息:" + "ActiveMq 发布的消息" + i);producer.send(message);session.commit();Thread.sleep(10000);}}}