4

Does the static ConcurrentHashmap need to be externaly synchronized using synchronize block or locks?

Bohemian
  • 412,405
  • 93
  • 575
  • 722
Vishal
  • 55
  • 1
  • 4

4 Answers4

5

Yes and no. It depends on what you're doing. ConcurrentHashMap is thread safe for all of its methods (e.g. get and put). However, it is not thread safe for non-atomic operations. Here is an example a method that performs a non-atomic operation:

public class Foo {
    Map<String, Object> map = new ConcurrentHashMap<String, Object>();

    public Object getFoo(String bar) {
        Object value = foo.get(bar);
        if (value == null) {
            value = new Object();
            map.put(bar, foo);
        }
        return value;
    }
}

The flaw here is that it is possible for two threads calling getFoo to receive a different Object. Remember that when dealing with a any data structure or type, even as simple as an int, non-atomic operations always require external synchronization. Classes such as AtomicInteger and ConcurrentHashMap assist in making some common operations thread safe, but do not protect against check-then-set operations such as in getFoo above.

Nate
  • 557
  • 3
  • 8
4

You only need external synchronization if you need to obtain a lock on the collection. The collection doesn't expose its internal locks.

ConcurrentMap has putIfAbsent, however if the creation of the object is expensive you may not want to use this.

 final ConcurrentMap<Key, Value> map =

 public Value get(Key key) {
     // allow concurrent read
     return map.get(key);
 }

 public Value getOrCreate(Key key) {
     // could put an extra check here to avoid synchronization.
     synchronized(map) {
        Value val = map.get(key);
        if (val == null)
           map.put(key, val = new ExpensiveValue(key));
        return val;
     }
 }
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

As far as I know all needed locking is done in this class so that you don't need to worry about it too much in case you are not doing some specific things and need it to function like that.

On http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html it says:

However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access.

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset.

So in case this does not represent any problems in your specific application you do not need to worry about it.

gw0
  • 1,533
  • 2
  • 12
  • 13
-1

No: No need to synchronise externally.

All methods on the java.util.concurrent classes are threadsafe.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 3
    Being threadsafe does not mean that you do not need to synchronize externally. We'd need to know what the map is being used for. (For the same reason, non-synchronized collection classes where introduced in Java, because the "threadsafety" of the original classes was pretty much both unnecessary and insufficient). – Thilo Jul 07 '11 at 11:49
  • I can't pick out any usage info from the question, certainly not enough for downvote someone. – Bohemian Jul 07 '11 at 11:56
  • That was a "relative downvote", to bring it on the same level as Peter's answer. I'd have upvoted him twice if I could instead. – Thilo Jul 07 '11 at 23:29