I have a class in which I am populating a map liveSocketsByDatacenter
from a single background thread every 30 seconds and then I have a method getNextSoc
It seems, that you can safely use ConcurrentHashMap
here instead of regular HashMap
and it should work.
In your current approach, using regular HashMap, you need to have synchronization of methods:
getNextSocket
, connectToZMQSockets
and updateLiveSockets
(everywhere you update or read the HashMap) like a sychronized
word before those methods or other lock on a monitor common for all these methods - And this is not because of ConcurrentModificationException
, but because without synchornization reading threads can see not updated values.
There is also problem with concurrent modification in the getLiveSocket, one of the simplest way to avoid this problem is to copy the listOfEndpoints to a new list before shuffle, like this:
private Optional getLiveSocket(final List endPoints) {
List listOfEndPoints = new ArrayList(endPoints);
if (!CollectionUtils.isEmpty(listOfEndPoints)) {
Collections.shuffle(listOfEndPoints);
for (SocketHolder obj : listOfEndPoints) {
if (obj.isLive()) {
return Optional.of(obj);
}
}
}
return Optional.absent();
}