Ministor_X

导航

多线程 访问集合 深复制与浅复制

最近在做一个项目,出现了一个很奇怪问题,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的时候,就把值直接拷进去,而不是进行复制,因为这个赋值是浅复制

 

posted on 2016-10-01 15:11  Ministor_X  阅读(272)  评论(0编辑  收藏  举报