Search code examples
javaconcurrenthashmap

Java ConcurrentHashMap atomic get if present


How do you perform a safe get if present operation on a Concurrent Hash Map? (same thing like putIfAbsent)

Bad example, not very thread safe (check then act situation):

ConcurrentMap<String, SomeObject> concMap = new ...

//... many putIfAbsent and remove operations

public boolean setOption(String id, Object option){
   SomeObject obj = concMap.get(id);

   if (obj != null){
      //what if this key has been removed from the map?
      obj.setOption(option);
      return true;
   }

   // in the meantime a putIfAbsent may have been called on the map and then this
   //setOption call is no longer correct

   return false;
}

Another bad example would be:

   public boolean setOption(String id, Object option){
       if (concMap.contains(id)){
           concMap.get(id).setOption(option);
           return true;
       }
       return false;
    }

The desirable thing here is to not bottleneck the add, remove and get operations by synchronizing them.

Thanks


Solution

  • What you appear to be trying to do is to lock a key over multiple operations. Only each operation is atomic. These is no simple way to lock a key, only to lock the map.

    However in the "what if I delete a key" case, all you can do is to delay the delete operation until after the setOption is called. The outcome should be the same.

    You appear to be trying to solve a problem which may not need to be solved. You haven't explained why calling setOption after a key is deleted or while a the key is waiting to be deleted is bad.