1

I'm using putIfAbsent to add values to a ConcurrentHashMap if they do not already exist as an atomic operations.

That all seems fine, but I could really do with being able to tell whether a new object was actually added.

The best idea I have is to check if the return value from putIfAbsent is null, that looks like it should work so long as we never put null values into the map (which ConcurrentHashMap doesn't allow anyway) but I was wondering if there was something I missed. Or is that the correct way to do it?

Tim B
  • 40,716
  • 16
  • 83
  • 128
  • 4
    Checking the return value of `putIfAbsent()` is the correct way. – Sean Bright Jan 25 '17 at 16:39
  • @SeanBright Yeah, that was the conclusion I came to too but "return == null" seemed a strange way to check for the fact that an operation had done something. – Tim B Jan 25 '17 at 16:46
  • Related: [Should you check if the map contains key before using putIfAbsent](http://stackoverflow.com/questions/3752194/should-you-check-if-the-map-containskey-before-using-concurrentmaps-putifabsent) – Mick Mnemonic Jan 25 '17 at 17:09

1 Answers1

3

The best way to use the CHM in this case is as such:

Object o = concurrentMap.get(key);

if(o == null){
   Object ret = concurrentMap.putIfAbsent(key, value);
   if(ret == null){
      o = ret;
   }
}
return o;

The get calls are non-blocking, so you want to leverage the non-blocking calls as much as you can. Continuously calling putIfAbsent can slow down performance if many are being invoked.

John Vint
  • 39,695
  • 7
  • 78
  • 108
  • But would defeat the purpose. You want the value in the map if it is there, and `get()` does that atomically. – Sean Bright Jan 25 '17 at 17:09
  • If you read the question carefully, OP does not ask for the return value, only to check if there is a value. – Mick Mnemonic Jan 25 '17 at 17:13
  • I'm not sure that is relevant. In the code example provided by this answer, the `get()` is required. If you feel that a more appropriate answer to the original question utilizes `containsKey()`, please create one. – Sean Bright Jan 25 '17 at 17:21
  • 1
    Readability _is_ relevant. Was just pointing out that this code sample doesn't directly answer the problem statement given by OP. But it would add little value for me to add a new answer that would basically just duplicate the double-check construct, which is the actual beef of this answer. – Mick Mnemonic Jan 25 '17 at 17:32