Reputation: 1076
I have a hashmap used in multiple threads at the same time. To make it thread safe I put it into a synchronized block:
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);
}
}
I thought if I put it into synchronized block I do not have to care about such stuff, but this Exception is thrown:
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
at java.util.HashMap$EntryIterator.next(HashMap.java:1476)
at java.util.HashMap$EntryIterator.next(HashMap.java:1474)
at myPackage.network.DeviceHandler.doClearing(DeviceHandler.java:51) // -> this line contains the for loop head of the code I showed
at java.lang.Thread.run(Thread.java:748)
Upvotes: 3
Views: 612
Reputation: 12751
It will only be thread-safe if every access (both reads and writes) to the map is performed via a synchronized
block.
ConcurrentModificationException
will be thrown when the map is being iterated on while it is being modified.
I would suggest you switch to a ConcurrentHashMap
which is thread-safe and will be a drop-in replacement.
Upvotes: 3