1

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

Community
  • 1
  • 1
michaeldd
  • 514
  • 2
  • 6
  • 18

1 Answers1

1

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.

cruftex
  • 5,545
  • 2
  • 20
  • 36
  • No problem for the late answer - thanks for answering at all. I will reply first. Basically I am looking for a good caching implementation to use as the standard in our new mvc framework (documentation to follow soon). I suppose the question is simply how important in each particular case it is to get the same/original value that was put into the cache. In most cases you can probably just return the new object, rather than specifically getting the original object incase of "return false". Currently I am testing with guava-cache as something did not seem to work at all for some reason. – michaeldd Jul 19 '16 at 15:41
  • Here is my other question: http://stackoverflow.com/questions/38399417/cache2k-java-lang-unsupportedoperationexception-loader-not-set. Maybe I am just making a silly mistake somewhere. – michaeldd Jul 19 '16 at 15:41
  • Just answered it :) – cruftex Jul 19 '16 at 15:42
  • If you want the cached object, for the else case, an option would be to use the entry processor / cache.invoke(). (Attention: As I remember correctly there will be a small change in the interface for the next version). The downside of the entry processor is more overhead. – cruftex Jul 19 '16 at 15:51
  • The entry processor works the same way as in JCache. I think it needs some more documentation, I probably will do an extra user guide chapter for it. – cruftex Jul 19 '16 at 15:53