What's the difference between ConcurrentHashMa

2018-12-31 12:37发布

I have a Map which is to be modified by several threads concurrently.

There seem to be three different synchronized Map implementations in the Java API:

  • Hashtable
  • Collections.synchronizedMap(Map)
  • ConcurrentHashMap

From what I understand, Hashtable is an old implementation (extending the obsolete Dictionary class), which has been adapted later to fit the Map interface. While it is synchronized, it seems to have serious scalability issues and is discouraged for new projects.

But what about the other two? What are the differences between Maps returned by Collections.synchronizedMap(Map) and ConcurrentHashMaps? Which one fits which situation?

18条回答
像晚风撩人
2楼-- · 2018-12-31 12:57

For your needs, use ConcurrentHashMap. It allows concurrent modification of the Map from several threads without the need to block them. Collections.synchronizedMap(map) creates a blocking Map which will degrade performance, albeit ensure consistency (if used properly).

Use the second option if you need to ensure data consistency, and each thread needs to have an up-to-date view of the map. Use the first if performance is critical, and each thread only inserts data to the map, with reads happening less frequently.

查看更多
何处买醉
3楼-- · 2018-12-31 12:58

There is one critical feature to note about ConcurrentHashMap other than concurrency feature it provides, which is fail-safe iterator. I have seen developers using ConcurrentHashMap just because they want to edit the entryset - put/remove while iterating over it. Collections.synchronizedMap(Map) does not provide fail-safe iterator but it provides fail-fast iterator instead. fail-fast iterators uses snapshot of the size of map which can not be edited during iteration.

查看更多
高级女魔头
4楼-- · 2018-12-31 13:07

As usual, there are concurrency--overhead--speed tradeoffs involved. You really need to consider the detailed concurrency requirements of your application to make a decision, and then test your code to see if it's good enough.

查看更多
长期被迫恋爱
5楼-- · 2018-12-31 13:08

ConcurrentHashMap is preferred when you can use it - though it requires at least Java 5.

It is designed to scale well when used by multiple threads. Performance may be marginally poorer when only a single thread accesses the Map at a time, but significantly better when multiple threads access the map concurrently.

I found a blog entry that reproduces a table from the excellent book Java Concurrency In Practice, which I thoroughly recommend.

Collections.synchronizedMap makes sense really only if you need to wrap up a map with some other characteristics, perhaps some sort of ordered map, like a TreeMap.

查看更多
皆成旧梦
6楼-- · 2018-12-31 13:09

You are right about HashTable, you can forget about it.

Your article mentions the fact that while HashTable and the synchronized wrapper class provide basic thread-safety by only allowing one thread at a time to access the map, this is not 'true' thread-safety since many compound operations still require additional synchronization, for example:

synchronized (records) {
  Record rec = records.get(id);
  if (rec == null) {
      rec = new Record(id);
      records.put(id, rec);
  }
  return rec;
}

However, don't think that ConcurrentHashMap is a simple alternative for a HashMap with a typical synchronized block as shown above. Read this article to understand its intricacies better.

查看更多
临风纵饮
7楼-- · 2018-12-31 13:09

ConcurrentHashMap is optimized for concurrent access.

Accesses don't lock the whole map but use a finer grained strategy, which improves scalability. There are also functional enhanvements specifically for concurrent access, e.g. concurrent iterators.

查看更多
登录 后发表回答