Search code examples
cache2k

Proper usage of cache.putIfAbsent() in Cache2k


I am wondering how to work with the putIfAbsent() method when using the Cache2k cache. In the ConcurrentHashMap for example, one works with the method like this:

Set<X> set = map.get(name);
if (set == null) {
    final Set<X> value = new HashSet<X>();
    set = map.putIfAbsent(name, value);
    if (set == null) {
        set = value;
    }
}

(Copied from Should you check if the map containsKey before using ConcurrentMap's putIfAbsent)

The Cache2K version returns a boolean. What does that mean and what does this tell me when more than 1 thread inserts a value using the same key.

Any help would be greatly appreciated as I am a bit unsure on how to deal with this. I am using the latest version 0.26-BETA.

Thanks and best regards, Michael


Solution

  • putIfAbsent() is equivalent to:

    if (!cache.containsKey(key)) {
      cache.put(key, value);
      return true;
    } else {
      return false;
    }
    

    except that it is executed atomically.

    The method returns true, if the value was inserted (that implies it was not existing before). Since it is executed atomically, only the thread, which value was successfully inserted, gets the true value.

    Mind that put may invoke a writer, if registered. The writer is not invoked, if the value is already present.

    The semantic of this method is identical to JCache/JSR107. This behavior might not make sense for all situations or is intuitive. See a discussion in https://github.com/jsr107/jsr107spec/issues/303.

    If you like, please try to explain in another question about your use case or you desired cache semantics, so we can discuss what the best approach might be.