4

I read an article about thread safe maps and got a question. Collections.synchronizedMap() proxies underlying map with adding synchronized blocks on each method. On the other hand ConcurrentHashMap doesn't lock the whole map on read/write operations. Which means all operations in multi thread system are faster.

So what are the benefits of using synchronizedMap() nowadays? I see the only:

  1. it's available since java 1.2 (vs java 1.5 for ConcurrentHashMap)
  2. can store nullable values (if underlying map can do it)

Are there any other situations when synchronizedMap() is better?

awfun
  • 2,316
  • 4
  • 31
  • 52
  • 1
    If the map you want to synchronise is not a `HashMap`? – RobCo Mar 30 '17 at 09:19
  • CHM allows for greater parallelization and scalability, but the increased complexity costs extra memory and performance, so it may not be worthwhile in a low-contention environment. Also, the `synchronizedMap()` can wrap various map types, like `EnumMap` or `LinkedHashMap`. – shmosel Mar 30 '17 at 09:22

4 Answers4

2

There is pros and cons associated with both Collections.synchronizedMap(map) and ConcurrentHashMap.

synchronizedMap is useful when you want data consistency. Each accessing thread will have an update view of the map which is achieved by blocking the map which in turn degrades it performance.

ConcurrentHashMap is useful when you needs to modify map frequently. Since it works on segmentation/partition of map several thread work simultaneously on it. But there is possibility that an accessing thread might not have an update view of map. Other advantage is that it is fail-safe. ConcurrentHashMap does not allow null keys or values.

Use ConcurrentHashMapif performance is high concern then data consistency.

Geek
  • 1,510
  • 14
  • 17
  • This isn't quite right. `ConcurrentHashMap` segments the table. Default 16 but you can pass higher values. This means you have a 1/16 chance that the entry you are accessing will be locked by another process. So you wil *always* have an up-to-date picture of the map but there is a smaller chance of performance penalty, whereas with `synchronizedMap` the whole thing gets locked. – robert Mar 31 '17 at 09:04
  • @robert, what you are saying about `ConcurrentHashMap` segmentation is correct and I'm not saying that `ConcurrentHashMap` will not give an updated view of map while accessing it. But there is possibility that `ConcurrentHashMap` will not return updated map view in high concurrent environment. – Geek Mar 31 '17 at 10:08
  • I guess it depends on how you define "updated" - a read won't reflect any pending writes ... but it's the write that hasn't been made yet, not the read that returns an out-of-date value. I think your answer just needs some clarification that's all. – robert Mar 31 '17 at 10:11
1

Not really. The only other case I can think of is easily making a custom map implementation thread safe.

Ede
  • 387
  • 2
  • 10
0

From the ConcurrentHashMap documentation:

"...there is not any support for locking the entire table in a way that prevents all access"

When iterating through ConcurrentHashMap elements you may see updates done at the same time by other threads. If you want to prevent such updates you can use Collections.synchronizedMap() instead and put iteration logic in synchronized(map) block.

Andrey Koshelev
  • 211
  • 1
  • 4
0

I can translate this with help of an anology of a Mutex vs. a Semaphore.

Just like any Mutex, synchronizedMap would allow only one thread at a time to access the backing map. This ensures that no other thread would be able to read/write entries from the map.

And for a ConcurrentHashMap, just like Semaphores we decide a concurrency level i.e. how many threads at one time can actually go and peek entries in your Map.

A research on when to use a Mutex and when to use a Semaphore could help you further clear your doubt.