问题来源
在写MQ队列的时候,局部变量不会受到多线程队列的影响
举个栗子
在监听中定义两个变量,一个是局部变量。然后设置监听的并发线程为2个,一次抓取线程的消息个数为20个,代码如下:
public int countPublic = 0;
@Override
@RabbitHandler
@RabbitListener(queues = "amz_advertisement:big_info", containerFactory = "rabbitListenerContainerFactoryAmzAdvertisementBig")
public void process(Message msg, Channel channel) {
int countPrivate = 0;
try {
countPrivate++;
countPublic++;
logger.error("countPrivate:{},countPublic:{}", countPrivate, countPublic);
} catch (Exception e) {
logger.error("bigInfo错误,错误信息为:{}", ExceptionUtil.formatException(e));
}
}
然后循环发送一组消息比如20个消息,具体代码如下
@RequestMapping("/sendMQ/{message}")
public Object sendMQ(@PathVariable("message") String message) throws InterruptedException {
for (int i=0;i<100;i++){
Thread.sleep(100);
amqpTemplateDelay.convertAndSend("message", "我是测试message的测试数据");
}
return "发送成功";
}
运行之后会发现局部变量不会改变,而类变量则会改变为什么呢?
这是因为Spring默认以单例模式创建对象,所以多线程模式下类变量就会存在线程安全问题。但是局部变量,在多线程模式下是线程安全的,各个线程之间的局部变量都是独享的。
总结
一点细小的差异,也可能导致大的错误。