Java 伪并发修改异常
我对一段持续触发ConcurrentModificationException的java代码有一些问题。我真的搞不清楚到底发生了什么,这是一个相当简单的静态类,不知道为什么它会抛出这个异常,因为一切都是同步的。这段代码已经被大量使用了好几年,所以奇怪的是,它在这一点上开始出现问题:Java 伪并发修改异常,java,synchronization,concurrentmodification,Java,Synchronization,Concurrentmodification,我对一段持续触发ConcurrentModificationException的java代码有一些问题。我真的搞不清楚到底发生了什么,这是一个相当简单的静态类,不知道为什么它会抛出这个异常,因为一切都是同步的。这段代码已经被大量使用了好几年,所以奇怪的是,它在这一点上开始出现问题: java.util.ConcurrentModificationException at java.util.LinkedList$ListItr.checkForComodification(Lin
java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:953)
at java.util.LinkedList$ListItr.next(LinkedList.java:886)
at DataSubscriptionManager.sendMessages(DataSubscriptionManager.java:18)
private static HashMap<DataClass,LinkedList<DataSubscriber>> subscriberMap = new HashMap();
public static void sendMessages(LinkedList messages, DataClass dataClass) {
synchronized (subscriberMap) {
LinkedList<DataSubscriber> subscribers = subscriberMap.get(dataClass);
if (subscribers != null) {
for (DataSubscriber sub: subscribers) { *** EXCEPTION HAPPENS HERE***
if (sub != null) {
sub.sendMessages(messages);
}
}
}
}
}
public static void addDataSubscriber(DataSubscriber sub, DataClass dataClass) {
synchronized (subscriberMap) {
LinkedList<DataSubscriber> subscribers = subscriberMap.get(dataClass);
if (subscribers == null) {
subscribers = new LinkedList();
subscriberMap.put(dataClass,subscribers);
}
while (subscribers.remove(sub)) {}
subscribers.add(sub);
}
}
public static void removeDataSubscriber(DataSubscriber sub, DataClass dataClass) {
synchronized (subscriberMap) {
LinkedList<DataSubscriber> subscribers = subscriberMap.get(dataClass);
subscribers.remove(sub);
}
}
java.util.ConcurrentModificationException
在java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:953)中
位于java.util.LinkedList$ListItr.next(LinkedList.java:886)
在DataSubscriptionManager.sendMessages(DataSubscriptionManager.java:18)
私有静态HashMap subscriberMap=新HashMap();
公共静态无效发送消息(LinkedList消息、DataClass DataClass){
已同步(订阅映射){
LinkedList订阅者=subscriberMap.get(数据类);
if(订阅服务器!=null){
对于(DataSubscriber sub:subscribers){***这里发生异常***
如果(sub!=null){
sub.sendMessages(消息);
}
}
}
}
}
公共静态void addDataSubscriber(DataSubscriber子,DataClass DataClass){
已同步(订阅映射){
LinkedList订阅者=subscriberMap.get(数据类);
if(订阅服务器==null){
订阅者=新的LinkedList();
subscriberMap.put(数据类,订阅者);
}
while(subscribers.remove(sub)){}
添加(sub);
}
}
public static void removeDataSubscriber(DataSubscriber,DataClass DataClass){
已同步(订阅映射){
LinkedList订阅者=subscriberMap.get(数据类);
删除(sub);
}
}
发生的情况是,在对集合进行迭代时,您的集合正在被修改
它可能是另一个线程,也可能是您的某个订阅服务器正在取消订阅,或订阅另一个数据类以响应它收到的消息。您可以尝试使用Collections.synchronizedList(订阅服务器)这可能有助于避免此问题。您可以添加一个stacktraceAre来查看此类上的所有方法吗?您确定没有将
LinkedList
的实例泄漏给其他未在地图上同步的类吗?是否有人正在修改消息列表,而DataSubscriptionManager正在处理它?这里有2个LinkedList,虽然DataSubscriber列表似乎是安全的,但消息列表可能会更改。发生的情况是,订阅服务器在检测到连接已断开时,其代码已从订阅列表中删除,因此它正在调用removeDataSubscriber,从而导致异常。但由于某种原因,java只从外部锁和内部锁启动堆栈跟踪,这使调试变得混乱。最后一位的可能重复可能是问题所在,sendMessages会导致调用addDataSubscriber。几乎可以肯定的是,它会这样做。可能需要某种程度的同步。