queue 是点对点模式,只能是一个生产者产生一个消息,被一个消费者消费。
queue 默认是存在于MQ的服务器中的,发送消息之后,消费者随时取。但是一定是一个消费者取,消费完消息也就没有了。
生产者:
public class QueueProduct {
public static void main(String[] args) throws Exception {
//创建工厂
ConnectionFactory facroty = new ActiveMQConnectionFactory("tcp://192.168.25.128:61616");
//利用工厂创建链接
Connection connection = facroty.createConnection();
//链接开启'
connection.start();
//使用 connection创建一个 session 对象
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//session 创建destination
Queue queue = session.createQueue("queue-test");
//session 创建 produce
MessageProducer producer = session.createProducer(queue);
//sesssion 创建message
TextMessage message = session.createTextMessage("hello activemq queue8");
//发送
producer.send(message);
producer.close();
session.close();
connection.close();
}
}
消费者方式一:
public class QueueCustomer {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.25.128:61616");
Connection connection = factory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-test");
MessageConsumer consumer = session.createConsumer(queue);
while(true){
Message message = consumer.receive(10000);
if(message == null){
break;
}
if(message instanceof TextMessage){
TextMessage textmessage = (TextMessage)message;
System.out.println(textmessage.getText());
}
}
connection.close();
session.close();
connection.close();
}
}
消费者方式二:
public class QueueCustomer2 {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.25.128:61616");
Connection connection = factory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-test");
MessageConsumer consumer = session.createConsumer(queue);
System.out.println("start");
//设置监听器,其实开启了一个新的线程。
//开启的应该是守护线程,当主线程结束的时候守护线程也随之结束
consumer.setMessageListener(new MessageListener() {
//接收消息,如果有消息才进入,如果没有消息就不会进入此方法
@Override
public void onMessage(Message message) {
if(message instanceof TextMessage){
TextMessage textMeaage = (TextMessage)message;
try {
System.out.println(textMeaage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
System.out.println("end");
//Thread.sleep(10000);
connection.close();
session.close();
connection.close();
}
}
针对第二种消费者的方式,做如下测试:
activeMQ中还有两个消息队列未被消费
执行消费者的代码结果如下,此时消息队列中明明有未被消费的消息却没被该消费者消费,为什么会出现这种情况?
再次执行消费者代码,此时activeMQ中的两个消息被消费了
获取队列消息的代码在 start之后,end之前,但是现在拿到的消息却显示在end之后,那么获取消息队列的方式应该是开启了一个新的线程或者是异步请求。
consumer.setMessageListener(new MessageListener(),设置监听器,其实开启了一个新的线程,开启的应该是守护线程,当主线程结束的时候守护线程也随之结束。执行的时候如果主线程先于守护线程执行完,那么消息就不会被消费,如果守护线程先执行完,才会消费队列中的消息。