Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java HashMap ConcurrentModification Exception despite using synchronized block

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)

like image 801
julienduchow Avatar asked Mar 28 '26 04:03

julienduchow


1 Answers

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.

like image 134
ᴇʟᴇvᴀтᴇ Avatar answered Mar 29 '26 16:03

ᴇʟᴇvᴀтᴇ