【发布时间】:2020-03-31 18:51:26
【问题描述】:
我有一个哈希图同时在多个线程中使用。为了使其线程安全,我将其放入同步块中:
private final Map<Long, DeviceConnection> mapConnections = new HashMap()<>;
...
synchronized (mapConnections) {
List<Long> toClear = new ArrayList<>();
for (Map.Entry<Long, AndroidSocketConnection> entry : mapConnections.entrySet()) {
if (entry.getValue().isReadyToRemove())) {
removed++;
toClear.add(entry.getKey());
}
}
for(Long toC : toClear) {
mapConnections.remove(toC);
}
}
我想如果我把它放到同步块中我不必关心这些东西,但是抛出了这个异常:
java.util.ConcurrentModificationException
在 java.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
在 java.util.HashMap$EntryIterator.next(HashMap.java:1476)
在 java.util.HashMap$EntryIterator.next(HashMap.java:1474)
at myPackage.network.DeviceHandler.doClearing(DeviceHandler.java:51) // -> 这一行包含我展示的代码的for循环头 p>
在 java.lang.Thread.run(Thread.java:748)
【问题讨论】:
-
是否还有其他代码在
mapConnections上运行? -
是的。这就是我使用同步块的原因。我一直在其他线程中从这张地图中放置和删除东西
-
其他线程是否也通过
synchronized (mapConnections)块访问? -
不,但是我在这个 HashSet 中引用了对象,我在其中更改了不在同步块中的属性,这可能是个问题吗?
-
这解释了
ConcurrentModificationException。至于在没有同步的情况下对其他对象进行操作,是的,这绝对是一个问题。它不会导致ConcurrentModificationException,但您会遇到难以理解且难以重现的错误。
标签: java multithreading concurrency hashmap concurrentmodification