onkami
onkami

Reputation: 9421

How to make atomic a nested iterative operation on ConcurrentHashMaps?

I have a ConcurrentHashMap subscriptions that contain another object (sessionCollection) and I need to do the following iterative operation:

  subscriptions.values().forEach(sessionCollection -> 
     sessionCollection.removeAllSubscriptionsOfSession(sessionId));

where sessionCollection.removeAllSubscriptionsOfSession does another iterative operation over a collection (also ConcurrentHashMap) inside sessionCollection:

// inside SessionCollection:
private final ConcurrentHashMap<String, CopyOnWriteArrayList<String>> topicsToSessions = 
 new ConcurrentHashMap<>();

public void removeAllSubscriptionsOfSession(String sessionId) {
    // Remove sessions from all topics on record
    topicsToSessions.keySet().forEach(topicSessionKey ->
     removeTopicFromSession(sessionId, topicSessionKey));
}

What would be the steps to make this overall atomic operation?

Upvotes: 2

Views: 182

Answers (1)

Andrew Lygin
Andrew Lygin

Reputation: 6197

ConcurrentHashMap has batch operations (forEach*()), but they are not atomic with respect to the whole map. The only way to make atomic batch changes on a map is to implement all the necessary synchronization yourself. For instance, by using synchronized blocks explicitly or by creating a wrapper (or an extension) for your map that will take care of synchronization where needed. In this case a simple HashMap will suffice since you have to do synchronization anyway:

public class SubscriptionsRegistry {
    private final Map<Integer, SessionCollection> map = new HashMap<>();

    public synchronized void removeSubscriptions(Integer sessionId) {
        map.values().forEach(...);
    }

    public synchronized void addSubscription(...) {
        ...
    }

    ...
}

You'll also want to protect the topics-to-sessions maps (at least their modifiable versions) from leaking outside your SubscriptionsRegistry, so nobody is able to modify them without proper synchronization.

Upvotes: 1

Related Questions