当前位置:   article > 正文

Springboot整合activemq(二):收发具有优先级的队列方法_springboot activemq-优先级队列

springboot activemq-优先级队列

在使用mq作为中间件做异步消息推送时,可能会遇到一个场景,就是消息在消费后执行一系列的逻辑到一半,突然遇到异常或者是断电等之类问题,这时消息在mq的队列中已经出队列,而正常逻辑没有执行完就异常终止,这样就可能会造成数据的缺失和数据的不完整,如何解决这个问题?其实挺简单的,就是在消息进入消费者消费的同时做一个记录,再在逻辑执行完成后再删除这条记录或者是改变这条记录的状态,同时,在项目初始化时或者是执行一个定时任务扫描这个记录表,如果存在则产生一条相同的记录发送到activemq中(相同的队列)。这样就能解决这个问题。然而,今天在开发中我又思考到一个问题,如图:

假设消息1没有消费完成,则消息1要重新进入队列,此时有一条消息4跟消息1操作的是同一条数据,如果消息1再进入队列,则4会在1之前消费掉,此时数据就会发生错乱,如果要保证消息1在消息4之前消费,则就需要对重新入队列的消息1进行一些操作来使得消息1优先消费。

activemq是提供对队列设置为具有优先级消息属性的功能,那么下面就要来实现具有优先级属性的消息队列:

第一步,进入activemq的conf文件夹下,修改activemq.xml配置文件,在<policyEntries>标签下插入一个配置:

<policyEntry queue="queue1" strictOrderDispatch="true" useCache="false" queuePrefetch="1" prioritizedMessages="true" />

完成后保存,并重启mq服务。这条配置就配置了对于queue1这个队列内的消息是具有优先级的属性的。

第二步,整合一个springboot+activemq的demo项目用于测试。

第三步,就是具体的代码实现了,首先我们来关注下springboot整合activemq的源码:

1.JmsMessagingTemplate这个类是实现发送消息的主要类,正常我们只需要在producer中注入这个类,调用其中发送消息的方法就能够实现消息的发送。具体代码如下:

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.jms.core.JmsMessagingTemplate;
  3. import org.springframework.stereotype.Service;
  4. import javax.jms.Destination;
  5. @Service
  6. public class TestProducer {
  7. @Autowired
  8. private JmsMessagingTemplate jmsMessagingTemplate;
  9. public void sendMsg(Destination destination, String text){
  10. jmsMessagingTemplate.convertAndSend(destination,text);
  11. }
  12. }

但是,此消息是不具有优先级的,接着往下看源码。

           2.在JmsMessagingTemplate类中实际上是封装了一个JmsTemplate这个类,实际上这个类才是真正实现消息发送的类,它只是将它进一步封装而已。

  1. package org.springframework.jms.core;
  2. import java.util.Map;
  3. import javax.jms.ConnectionFactory;
  4. import javax.jms.Destination;
  5. import javax.jms.JMSException;
  6. import javax.jms.Session;
  7. import org.springframework.beans.factory.InitializingBean;
  8. import org.springframework.jms.InvalidDestinationException;
  9. import org.springframework.jms.JmsException;
  10. import org.springframework.jms.support.converter.MessageConverter;
  11. import org.springframework.jms.support.converter.MessagingMessageConverter;
  12. import org.springframework.jms.support.destination.DestinationResolutionException;
  13. import org.springframework.lang.Nullable;
  14. import org.springframework.messaging.Message;
  15. import org.springframework.messaging.MessagingException;
  16. import org.springframework.messaging.converter.MessageConversionException;
  17. import org.springframework.messaging.core.AbstractMessagingTemplate;
  18. import org.springframework.messaging.core.MessagePostProcessor;
  19. import org.springframework.util.Assert;
  20. public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination> implements JmsMessageOperations, InitializingBean {
  21. @Nullable
  22. private JmsTemplate jmsTemplate;
  23. private MessageConverter jmsMessageConverter = new MessagingMessageConverter();
  24. private boolean converterSet;
  25. @Nullable
  26. private String defaultDestinationName;
  27. public JmsMessagingTemplate() {
  28. }
  29. public JmsMessagingTemplate(ConnectionFactory connectionFactory) {
  30. this.jmsTemplate = new JmsTemplate(connectionFactory);
  31. }
  32. public JmsMessagingTemplate(JmsTemplate jmsTemplate) {
  33. Assert.notNull(jmsTemplate, "JmsTemplate must not be null");
  34. this.jmsTemplate = jmsTemplate;
  35. }
  36. public void setConnectionFactory(ConnectionFactory connectionFactory) {
  37. if (this.jmsTemplate != null) {
  38. this.jmsTemplate.setConnectionFactory(connectionFactory);
  39. } else {
  40. this.jmsTemplate = new JmsTemplate(connectionFactory);
  41. }
  42. }
  43. @Nullable
  44. public ConnectionFactory getConnectionFactory() {
  45. return this.jmsTemplate != null ? this.jmsTemplate.getConnectionFactory() : null;
  46. }
  47. public void setJmsTemplate(@Nullable JmsTemplate jmsTemplate) {
  48. this.jmsTemplate = jmsTemplate;
  49. }
  50. @Nullable
  51. public JmsTemplate getJmsTemplate() {
  52. return this.jmsTemplate;
  53. }
  54. public void setJmsMessageConverter(MessageConverter jmsMessageConverter) {
  55. Assert.notNull(jmsMessageConverter, "MessageConverter must not be null");
  56. this.jmsMessageConverter = jmsMessageConverter;
  57. this.converterSet = true;
  58. }
  59. public MessageConverter getJmsMessageConverter() {
  60. return this.jmsMessageConverter;
  61. }
  62. public void setDefaultDestinationName(@Nullable String defaultDestinationName) {
  63. this.defaultDestinationName = defaultDestinationName;
  64. }
  65. @Nullable
  66. public String getDefaultDestinationName() {
  67. return this.defaultDestinationName;
  68. }
  69. public void afterPropertiesSet() {
  70. Assert.notNull(this.jmsTemplate, "Property 'connectionFactory' or 'jmsTemplate' is required");
  71. if (!this.converterSet && this.jmsTemplate.getMessageConverter() != null) {
  72. ((MessagingMessageConverter)this.jmsMessageConverter).setPayloadConverter(this.jmsTemplate.getMessageConverter());
  73. }
  74. }
  75. private JmsTemplate obtainJmsTemplate() {
  76. Assert.state(this.jmsTemplate != null, "No JmsTemplate set");
  77. return this.jmsTemplate;
  78. }
  79. public void send(Message<?> message) {
  80. Destination defaultDestination = (Destination)this.getDefaultDestination();
  81. if (defaultDestination != null) {
  82. this.send(defaultDestination, message);
  83. } else {
  84. this.send(this.getRequiredDefaultDestinationName(), message);
  85. }
  86. }
  87. public void convertAndSend(Object payload) throws MessagingException {
  88. this.convertAndSend((Object)payload, (MessagePostProcessor)null);
  89. }
  90. public void convertAndSend(Object payload, @Nullable MessagePostProcessor postProcessor) throws MessagingException {
  91. Destination defaultDestination = (Destination)this.getDefaultDestination();
  92. if (defaultDestination != null) {
  93. this.convertAndSend((Object)defaultDestination, payload, (MessagePostProcessor)postProcessor);
  94. } else {
  95. this.convertAndSend(this.getRequiredDefaultDestinationName(), payload, postProcessor);
  96. }
  97. }
  98. public void send(String destinationName, Message<?> message) throws MessagingException {
  99. this.doSend(destinationName, message);
  100. }
  101. public void convertAndSend(String destinationName, Object payload) throws MessagingException {
  102. this.convertAndSend(destinationName, payload, (Map)null);
  103. }
  104. public void convertAndSend(String destinationName, Object payload, @Nullable Map<String, Object> headers) throws MessagingException {
  105. this.convertAndSend(destinationName, payload, headers, (MessagePostProcessor)null);
  106. }
  107. public void convertAndSend(String destinationName, Object payload, @Nullable MessagePostProcessor postProcessor) throws MessagingException {
  108. this.convertAndSend(destinationName, payload, (Map)null, postProcessor);
  109. }
  110. public void convertAndSend(String destinationName, Object payload, @Nullable Map<String, Object> headers, @Nullable MessagePostProcessor postProcessor) throws MessagingException {
  111. Message<?> message = this.doConvert(payload, headers, postProcessor);
  112. this.send(destinationName, message);
  113. }
  114. @Nullable
  115. public Message<?> receive() {
  116. Destination defaultDestination = (Destination)this.getDefaultDestination();
  117. return defaultDestination != null ? this.receive(defaultDestination) : this.receive(this.getRequiredDefaultDestinationName());
  118. }
  119. @Nullable
  120. public <T> T receiveAndConvert(Class<T> targetClass) {
  121. Destination defaultDestination = (Destination)this.getDefaultDestination();
  122. return defaultDestination != null ? this.receiveAndConvert(defaultDestination, targetClass) : this.receiveAndConvert(this.getRequiredDefaultDestinationName(), targetClass);
  123. }
  124. @Nullable
  125. public Message<?> receive(String destinationName) throws MessagingException {
  126. return this.doReceive(destinationName);
  127. }
  128. @Nullable
  129. public <T> T receiveAndConvert(String destinationName, Class<T> targetClass) throws MessagingException {
  130. Message<?> message = this.doReceive(destinationName);
  131. return message != null ? this.doConvert(message, targetClass) : null;
  132. }
  133. @Nullable
  134. public Message<?> sendAndReceive(Message<?> requestMessage) {
  135. Destination defaultDestination = (Destination)this.getDefaultDestination();
  136. return defaultDestination != null ? this.sendAndReceive(defaultDestination, requestMessage) : this.sendAndReceive(this.getRequiredDefaultDestinationName(), requestMessage);
  137. }
  138. @Nullable
  139. public Message<?> sendAndReceive(String destinationName, Message<?> requestMessage) throws MessagingException {
  140. return this.doSendAndReceive(destinationName, requestMessage);
  141. }
  142. @Nullable
  143. public <T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass) throws MessagingException {
  144. return this.convertSendAndReceive(destinationName, request, (Map)null, (Class)targetClass);
  145. }
  146. @Nullable
  147. public <T> T convertSendAndReceive(Object request, Class<T> targetClass) {
  148. return this.convertSendAndReceive((Object)request, (Class)targetClass, (MessagePostProcessor)null);
  149. }
  150. @Nullable
  151. public <T> T convertSendAndReceive(String destinationName, Object request, @Nullable Map<String, Object> headers, Class<T> targetClass) throws MessagingException {
  152. return this.convertSendAndReceive(destinationName, request, headers, targetClass, (MessagePostProcessor)null);
  153. }
  154. @Nullable
  155. public <T> T convertSendAndReceive(Object request, Class<T> targetClass, @Nullable MessagePostProcessor postProcessor) {
  156. Destination defaultDestination = (Destination)this.getDefaultDestination();
  157. return defaultDestination != null ? this.convertSendAndReceive((Object)defaultDestination, request, (Class)targetClass, (MessagePostProcessor)postProcessor) : this.convertSendAndReceive(this.getRequiredDefaultDestinationName(), request, targetClass, postProcessor);
  158. }
  159. @Nullable
  160. public <T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass, @Nullable MessagePostProcessor requestPostProcessor) throws MessagingException {
  161. return this.convertSendAndReceive(destinationName, request, (Map)null, targetClass, requestPostProcessor);
  162. }
  163. @Nullable
  164. public <T> T convertSendAndReceive(String destinationName, Object request, @Nullable Map<String, Object> headers, Class<T> targetClass, @Nullable MessagePostProcessor postProcessor) {
  165. Message<?> requestMessage = this.doConvert(request, headers, postProcessor);
  166. Message<?> replyMessage = this.sendAndReceive(destinationName, requestMessage);
  167. return replyMessage != null ? this.getMessageConverter().fromMessage(replyMessage, targetClass) : null;
  168. }
  169. protected void doSend(Destination destination, Message<?> message) {
  170. try {
  171. this.obtainJmsTemplate().send(destination, this.createMessageCreator(message));
  172. } catch (JmsException var4) {
  173. throw this.convertJmsException(var4);
  174. }
  175. }
  176. protected void doSend(String destinationName, Message<?> message) {
  177. try {
  178. this.obtainJmsTemplate().send(destinationName, this.createMessageCreator(message));
  179. } catch (JmsException var4) {
  180. throw this.convertJmsException(var4);
  181. }
  182. }
  183. @Nullable
  184. protected Message<?> doReceive(Destination destination) {
  185. try {
  186. javax.jms.Message jmsMessage = this.obtainJmsTemplate().receive(destination);
  187. return this.convertJmsMessage(jmsMessage);
  188. } catch (JmsException var3) {
  189. throw this.convertJmsException(var3);
  190. }
  191. }
  192. @Nullable
  193. protected Message<?> doReceive(String destinationName) {
  194. try {
  195. javax.jms.Message jmsMessage = this.obtainJmsTemplate().receive(destinationName);
  196. return this.convertJmsMessage(jmsMessage);
  197. } catch (JmsException var3) {
  198. throw this.convertJmsException(var3);
  199. }
  200. }
  201. @Nullable
  202. protected Message<?> doSendAndReceive(Destination destination, Message<?> requestMessage) {
  203. try {
  204. javax.jms.Message jmsMessage = this.obtainJmsTemplate().sendAndReceive(destination, this.createMessageCreator(requestMessage));
  205. return this.convertJmsMessage(jmsMessage);
  206. } catch (JmsException var4) {
  207. throw this.convertJmsException(var4);
  208. }
  209. }
  210. @Nullable
  211. protected Message<?> doSendAndReceive(String destinationName, Message<?> requestMessage) {
  212. try {
  213. javax.jms.Message jmsMessage = this.obtainJmsTemplate().sendAndReceive(destinationName, this.createMessageCreator(requestMessage));
  214. return this.convertJmsMessage(jmsMessage);
  215. } catch (JmsException var4) {
  216. throw this.convertJmsException(var4);
  217. }
  218. }
  219. private JmsMessagingTemplate.MessagingMessageCreator createMessageCreator(Message<?> message) {
  220. return new JmsMessagingTemplate.MessagingMessageCreator(message, this.getJmsMessageConverter());
  221. }
  222. protected String getRequiredDefaultDestinationName() {
  223. String name = this.getDefaultDestinationName();
  224. if (name == null) {
  225. throw new IllegalStateException("No 'defaultDestination' or 'defaultDestinationName' specified. Check configuration of JmsMessagingTemplate.");
  226. } else {
  227. return name;
  228. }
  229. }
  230. @Nullable
  231. protected Message<?> convertJmsMessage(@Nullable javax.jms.Message message) {
  232. if (message == null) {
  233. return null;
  234. } else {
  235. try {
  236. return (Message)this.getJmsMessageConverter().fromMessage(message);
  237. } catch (Exception var3) {
  238. throw new MessageConversionException("Could not convert '" + message + "'", var3);
  239. }
  240. }
  241. }
  242. protected MessagingException convertJmsException(JmsException ex) {
  243. if (!(ex instanceof DestinationResolutionException) && !(ex instanceof InvalidDestinationException)) {
  244. return (MessagingException)(ex instanceof org.springframework.jms.support.converter.MessageConversionException ? new MessageConversionException(ex.getMessage(), ex) : new MessagingException(ex.getMessage(), ex));
  245. } else {
  246. return new org.springframework.messaging.core.DestinationResolutionException(ex.getMessage(), ex);
  247. }
  248. }
  249. private static class MessagingMessageCreator implements MessageCreator {
  250. private final Message<?> message;
  251. private final MessageConverter messageConverter;
  252. public MessagingMessageCreator(Message<?> message, MessageConverter messageConverter) {
  253. this.message = message;
  254. this.messageConverter = messageConverter;
  255. }
  256. public javax.jms.Message createMessage(Session session) throws JMSException {
  257. try {
  258. return this.messageConverter.toMessage(this.message, session);
  259. } catch (Exception var3) {
  260. throw new MessageConversionException("Could not convert '" + this.message + "'", var3);
  261. }
  262. }
  263. }
  264. }

我们可以跟踪方法的执行,进入到JmsTemplate这个类中,发现里面336行封装着一个方法。

  1. protected void doSend(MessageProducer producer, Message message) throws JMSException {
  2. if (this.deliveryDelay >= 0L) {
  3. producer.setDeliveryDelay(this.deliveryDelay);
  4. }
  5. if (this.isExplicitQosEnabled()) {
  6. producer.send(message, this.getDeliveryMode(), this.getPriority(), this.getTimeToLive());
  7. } else {
  8. producer.send(message);
  9. }
  10. }

这里就可以看到producer这个对象调用的send方法中有设置几个参数:

(1)、message不用说了,就是要发送的消息内容;

(2)、Delivery Mode翻译过来就是发送模式发送模式;

(3)、priority!这就是我们要找的优先级,传入0-9整数,数字越大优先级越高;

(4)、timeToLive延时发送时间;

Ok,到这里我们就可以看到,如果要执行这个方法就只需要isExplicitQosEnabled()这个方法返回值为true。

再看代码的第175行的方法:

  1. public void setQosSettings(QosSettings settings) {
  2. Assert.notNull(settings, "Settings must not be null");
  3. this.setExplicitQosEnabled(true);
  4. this.setDeliveryMode(settings.getDeliveryMode());
  5. this.setPriority(settings.getPriority());
  6. this.setTimeToLive(settings.getTimeToLive());
  7. }

这个方法就是设置上面几个参数的设置,只需传入QosSettings这个对象就行。

来看JmsTemplate这个类的构造方法:

  1. public JmsTemplate() {
  2. this.transactionalResourceFactory = new JmsTemplate.JmsTemplateResourceFactory();
  3. this.messageIdEnabled = true;
  4. this.messageTimestampEnabled = true;
  5. this.pubSubNoLocal = false;
  6. this.receiveTimeout = 0L;
  7. this.deliveryDelay = -1L;
  8. this.explicitQosEnabled = false;
  9. this.deliveryMode = 2;
  10. this.priority = 4;
  11. this.timeToLive = 0L;
  12. this.initDefaultStrategies();
  13. }

可以看到几个参数的默认值,也就是没有执行任何操作时如果将explicitQosEnabled设置为true则该消息发送出去优先级默认为4。

          3.所以我们将生产者代码进行修改:

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.jms.core.JmsMessagingTemplate;
  3. import org.springframework.jms.core.JmsTemplate;
  4. import org.springframework.jms.support.QosSettings;
  5. import org.springframework.stereotype.Service;
  6. import javax.jms.DeliveryMode;
  7. import javax.jms.Destination;
  8. @Service
  9. public class TestProducer {
  10. @Autowired
  11. private JmsMessagingTemplate jmsMessagingTemplate;
  12. public void sendMsg(Destination destination, String text, int priority){
  13. //获取jmsTemplate对象
  14. JmsTemplate jmsTemplate = jmsMessagingTemplate.getJmsTemplate();
  15. //创建QosSettings对象
  16. QosSettings settings = new QosSettings();
  17. //设置优先级
  18. settings.setPriority(priority);
  19. //设置发送模式
  20. settings.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
  21. //设置延时发送时间
  22. settings.setTimeToLive(1000L);
  23. //将设置传入
  24. jmsTemplate.setQosSettings(settings);
  25. //发送消息
  26. jmsMessagingTemplate.convertAndSend(destination,text);
  27. }
  28. }

这样生产者就写完了。

           4.测试

           首先,先写一个消费者,监听队列queue1:

  1. import org.springframework.jms.annotation.JmsListener;
  2. import org.springframework.stereotype.Component;
  3. @Component
  4. public class TestConsumer {
  5. @JmsListener(destination = "queue1")
  6. public void receiveTest(String text){
  7. System.out.println("接收到queue1发送的消息:"+text);
  8. }
  9. }

再写一个controller类可以通过前端调用发送消息的方法:

  1. import com.example.springboot.mq.demo.producer.TestProducer;
  2. import org.apache.activemq.command.ActiveMQQueue;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. import javax.jms.Destination;
  7. import java.util.Random;
  8. @RestController
  9. public class TestController {
  10. @Autowired
  11. private TestProducer producer;
  12. @RequestMapping("/test")
  13. public String test(){
  14. Destination destination = new ActiveMQQueue("queue1");
  15. Random random = new Random(10);
  16. for (int i=0;i < 100;i++){
  17. //随机产生优先级数字
  18. int priority = random.nextInt(9);
  19. producer.sendMsg(destination,"消息No."+i+"优先级为:"+priority,priority);
  20. }
  21. return "发送成功";
  22. }
  23. }

然后启动项目进行测试,测试结果:

  1. 发送消息优先级为:0
  2. 发送消息优先级为:6
  3. 发送消息优先级为:6
  4. 发送消息优先级为:0
  5. 发送消息优先级为:4
  6. 发送消息优先级为:1
  7. 发送消息优先级为:1
  8. 发送消息优先级为:4
  9. 发送消息优先级为:3
  10. 发送消息优先级为:1
  11. 发送消息优先级为:1
  12. 发送消息优先级为:2
  13. 发送消息优先级为:6
  14. 发送消息优先级为:6
  15. 发送消息优先级为:3
  16. 发送消息优先级为:3
  17. 发送消息优先级为:1
  18. 发送消息优先级为:1
  19. 发送消息优先级为:4
  20. 发送消息优先级为:7
  21. 发送消息优先级为:8
  22. 发送消息优先级为:7
  23. 发送消息优先级为:6
  24. 发送消息优先级为:8
  25. 发送消息优先级为:5
  26. 发送消息优先级为:1
  27. 发送消息优先级为:5
  28. 发送消息优先级为:5
  29. 发送消息优先级为:8
  30. 发送消息优先级为:8
  31. 发送消息优先级为:2
  32. 发送消息优先级为:8
  33. 发送消息优先级为:6
  34. 发送消息优先级为:8
  35. 发送消息优先级为:7
  36. 发送消息优先级为:1
  37. 发送消息优先级为:7
  38. 发送消息优先级为:1
  39. 发送消息优先级为:0
  40. 发送消息优先级为:4
  41. 发送消息优先级为:8
  42. 发送消息优先级为:1
  43. 发送消息优先级为:8
  44. 发送消息优先级为:0
  45. 发送消息优先级为:7
  46. 发送消息优先级为:5
  47. 发送消息优先级为:6
  48. 发送消息优先级为:0
  49. 发送消息优先级为:2
  50. 发送消息优先级为:4

接收到的消息:

  1. 消息内容:1优先级为:6
  2. 消息内容:20优先级为:8
  3. 消息内容:23优先级为:8
  4. 消息内容:28优先级为:8
  5. 消息内容:29优先级为:8
  6. 消息内容:31优先级为:8
  7. 消息内容:33优先级为:8
  8. 消息内容:40优先级为:8
  9. 消息内容:42优先级为:8
  10. 消息内容:19优先级为:7
  11. 消息内容:21优先级为:7
  12. 消息内容:34优先级为:7
  13. 消息内容:36优先级为:7
  14. 消息内容:44优先级为:7
  15. 消息内容:2优先级为:6
  16. 消息内容:12优先级为:6
  17. 消息内容:13优先级为:6
  18. 消息内容:22优先级为:6
  19. 消息内容:32优先级为:6
  20. 消息内容:46优先级为:6
  21. 消息内容:24优先级为:5
  22. 消息内容:26优先级为:5
  23. 消息内容:27优先级为:5
  24. 消息内容:45优先级为:5
  25. 消息内容:4优先级为:4
  26. 消息内容:7优先级为:4
  27. 消息内容:18优先级为:4
  28. 消息内容:39优先级为:4
  29. 消息内容:49优先级为:4
  30. 消息内容:8优先级为:3
  31. 消息内容:14优先级为:3
  32. 消息内容:15优先级为:3
  33. 消息内容:11优先级为:2
  34. 消息内容:30优先级为:2
  35. 消息内容:48优先级为:2
  36. 消息内容:5优先级为:1
  37. 消息内容:6优先级为:1
  38. 消息内容:9优先级为:1
  39. 消息内容:10优先级为:1
  40. 消息内容:16优先级为:1
  41. 消息内容:17优先级为:1
  42. 消息内容:25优先级为:1
  43. 消息内容:35优先级为:1
  44. 消息内容:37优先级为:1
  45. 消息内容:41优先级为:1
  46. 消息内容:0优先级为:0
  47. 消息内容:3优先级为:0
  48. 消息内容:38优先级为:0
  49. 消息内容:43优先级为:0
  50. 消息内容:47优先级为:0

结果显示,除第一条外,其他消息的接收全部是按消息的优先级出队列。所以大功告成,至于第一个消息为什么没有按优先级出队列后续我再研究一下。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/763282
推荐阅读
相关标签
  

闽ICP备14008679号