25
Sep

ConcurrentMap Interface Methods

Did you know that the java.util.concurrency.ConcurrentMap provides some very useful methods beyond the ones provided by the traditional java.util.Map interface?

The java.util.concurrency.ConcurrentMap is implemented by java.util.concurrency.ConcurrentHashMap class which provides extreme scalability when used in a multi-threaded fashion, while still providing thread safety.

java.util.concurrency.ConcurrentMap interface provides four additional methods to the java.util.Map interface that are executed atomically without additional external synchronization needs:

  1. putIfAbsent(key, value): which puts an item if the key is not already in the map, associated with a value.
  2. remove(key, value): which removes an entry if the key maps to the given value.
  3. replace(key, value): which replaces an entry if the key maps to some value already in the map.
  4. replace(key, oldValue, newValue): which replaces an entry if the key maps to the oldValue, replacing it by newValue.

The interesting thing is that all these operations are performed atomically, what would not be possible to be externally implemented with ConcurrentHashMap as it uses a variable number of locks to improve scalability, with 16 locks by default and the lock guarding each entry may vary.

Bellow, we see the putIfAbsent method at work:


package collections;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class ConcurrentMapTest {

  private ConcurrentMap<String, String> map = new ConcurrentHashMap<String, String>();

  public static void main(String[] args) {
    new ConcurrentMapTest().test();
  }

  private void test() {
    map.put("key 1", "value 1");
    String value = map.putIfAbsent("key 1", "value 2");
    System.out.println(map);
    System.out.println(value);

    value = map.putIfAbsent("key 2", "value 2");
    System.out.println(map);
    System.out.println(value);
  }
}



Describing what is done, we first add the value "value 1" with key "key 1". Then we use putIfAbsent to put value "value 2" associated with key "key 1". As key "key 1" is not absent in the map, it returns the value already in the map and does not alter its contents. So, when printing the map, what is printed is:
{key 1=value 1} and the value returned prints "value 1".

The other piece of code does the same but uses a key that is absent in the map, what causes the entry to be added, so when printing the map it prints: {key 1=value 1, key 2=value 2} and the value returned is null as this key did not map to any value before.

The concurrent collections provide extreme scalability and, as we saw, it's not just that: they also provide nice new features as well. Take a look at the documentation and see what they can do for you. I also recommend buying the great book Java Concurrency in Practice. It's a great source of information. I bought it for my Kindle and I'm reading it for the second time. It's such a must have for any Java programmer.


free b2evolution skin

Trackback address for this post

Trackback URL (right click and copy shortcut/link location)

No feedback yet

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
PoorExcellent
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)