java.util.ConcurrentModificationException
对于这个异常记忆太深刻了,因为面试被问到过!!!而且没准备,答得一塌糊涂~~
今天,在项目上遇到了这个问题,查日志看到抛出异常的地方是在一个遍历查询的方法,没有增删改的操作,于是只能往上翻代码
整理一个整个链路,大概流程是:
// 以下为伪代码
// 方法入口
public void submit(SaveData data){
List list = saveToDB(data);
this.sendToMq(list);
}
// 保存数据,然后推给下游系统
public List saveToDB(SaveData data){
List list = new ArrayList();
// ignore
this.syncSendToRemote(list)
return list;
}
// 推MQ
public void sendToMq(List list){
for(Item item : list){ // throws ConcurrentModificationException
// read and send
}
}
// 推给下游系统
public void syncSendToRemote(List list){
executor.execute(()-> {
list.removeIf(item -> item.name == null);
// send
});
}
抛出异常的地方,在sendToMq()
的遍历方法,看看list哪里会用到:
- 首先,list是在
saveToDB
中创建 - list会传给
syncSendToRemote
- 最后才把list传给
sendToMq()
这就很明显了,syncSendToRemote
是个异步方法,也就是说,syncSendToRemote
和 sendToMq
有可能在同时执行,就相当于一个典型的并发问题了,两个线程同时操作list(大概又是前段时间为了优化接口改出来的问题~)
接下来,就是面试题中的“你有遇到过ConcurrentModificationException吗?如何解决?”的问题了。。(晚点更新)
网友评论