6
workObjectMap.computeIfPresent(key, (k,v) -> {
    v.memberIdSet.addAll(memberIdSet);
    v.memberPositionSet.addAll(memberPositionSet);
    return v;
});
// If it.remove() in run() is called at this point,
// there is a risk of the same work being done twice
workObjectMap.putIfAbsent(key, new WorkObjectValue(memberIdSet, memberPositionSet));

I have the above code. In a separate thread I may be removing from the workObjectMap. I want an atomic function that modifies the value if the key is present, and if its not, it puts the key/value.

In my current code, there is a chance that the remove will happen in between the computeIfPresent and putIfAbsent so that the same item that was already added to the map, would be added again.

How do I block any removes in between these 2 method calls? (computeIfPresent and putIfAbsent)

Didier L
  • 18,905
  • 10
  • 61
  • 103
Camilla
  • 160
  • 9

1 Answers1

6

Use Map.compute():

workObjectMap.compute(key, (k,v) -> {
    if (v == null) return new WorkObjectValue(memberIdSet, memberPositionSet);
    v.memberIdSet.addAll(memberIdSet);
    v.memberPositionSet.addAll(memberPositionSet);
    return v;
});

Note that the ConcurrentHashMap Javadoc explicitly states that this is atomic.

Didier L
  • 18,905
  • 10
  • 61
  • 103