最近在做一个项目,出现了一个很奇怪问题,debug的模式下,一步步的来,发现异步发送一个mq消息没问题,但是到了测试环境就会有问题
代码如下:
List<B> dataList = new ArrayList<>();; for(B b:A.getB()){ //处理逻辑 message = Butils.createMessage(B, false);// dataList.add(message); // dataListTemp.addAll(dataList); syncCrtExecutor.submit(new BCallable(dataList, qName, amqSender)); dataList.clear();//清空消息内容 }
public class BCallabe implements Callable<Boolean> {
private static final Logger logger = LoggerFactory.getLogger(BCallabe .class);
private List<B> dataList = new ArrayList<>();
private String qname;
private AMQQueueSender amqQueueSender;
public BCallable(List<B> dataList, String qname;,
AMQQueueSender amqQueueSender) {
this.dataList=dataList;
this.qname = qname;
this.amqQueueSender =amqQueueSender;
}
@Override
public Boolean call() throws Exception {
try {
logger.info("MQ消息推送给xxx{}", JsonUtil.toString(dataList));
amqQueueSender.send(JsonUtil.toString(dataList),
qname);
} catch (Exception e) {
logger.error("MQ消息发送失败{}", e);
}
return true;
}
}
因为想发一个消息,所以每次获取到的datalist进行转发,但是我又想到消息比较多,需要清空,所以加了dataList.clear();//清空消息内容,结果导致Bcallable的消息在浅拷贝,还是用到这个值,导致每次发送消息都是为空
当时就想这个值线程是异步,在测试环境下就会直接走到clear了,导致datalist的值被清空,Bcallable拿不到这个datailst的值
刚开始想的是在外层写个复制,然后复制在放入callable,后来放弃,目前想到的解决方案:
public BCallable(List<B> dataList, String qname;, AMQQueueSender amqQueueSender) { this.dataList.addAll(dataList); this.qname = qname; this.amqQueueSender =amqQueueSender; }
在构造callable的时候,就把值直接拷进去,而不是进行复制,因为这个赋值是浅复制