Java ConcurrentHashMap 和 Collections.synchronizedMap(Map) 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/510632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:34:20  来源:igfitidea点击:

What's the difference between ConcurrentHashMap and Collections.synchronizedMap(Map)?

javadictionaryconcurrency

提问by Henning

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

我有一个要由多个线程同时修改的 Map。

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

Java API 中似乎有三种不同的同步 Map 实现:

  • Hashtable
  • Collections.synchronizedMap(Map)
  • ConcurrentHashMap
  • Hashtable
  • Collections.synchronizedMap(Map)
  • ConcurrentHashMap

From what I understand, Hashtableis an old implementation (extending the obsolete Dictionaryclass), which has been adapted later to fit the Mapinterface. While it issynchronized, it seems to have serious scalability issuesand is discouraged for new projects.

据我了解,这Hashtable是一个旧的实现(扩展过时的Dictionary类),后来经过调整以适应Map接口。虽然它同步的,但它似乎存在严重的可扩展性问题,不鼓励用于新项目。

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

但是另外两个呢?Collections.synchronizedMap(Map)ConcurrentHashMaps返回的 Map 有什么区别?哪个适合哪种情况?

采纳答案by Yuval Adam

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).

根据您的需要,请使用ConcurrentHashMap. 它允许从多个线程并发修改 Map 而无需阻止它们。Collections.synchronizedMap(map)创建一个阻塞 Map 会降低性能,尽管确保一致性(如果使用得当)。

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.

如果需要确保数据一致性,则使用第二个选项,并且每个线程都需要具有最新的地图视图。如果性能至关重要,则使用第一个,并且每个线程仅将数据插入到映射中,读取发生的频率较低。

回答by Bill Michell

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

当您可以使用 ConcurrentHashMap 时,首选它 - 尽管它至少需要 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.

它被设计为在被多线程使用时可以很好地扩展。当一次只有一个线程访问 Map 时,性能可能会稍差一些,但当多个线程同时访问 Map 时,性能会好得多。

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

我找到了一个博客条目,它从我强烈推荐的优秀书籍Java Concurrency In Practice中复制了一个表。

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.

Collections.synchronizedMap 只有当你需要用一些其他特征来包装一个地图时才有意义,也许是某种有序的地图,比如 TreeMap。

回答by Zach Scrivena

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.

像往常一样,涉及并发-开销-速度权衡。您确实需要考虑应用程序的详细并发要求来做出决定,然后测试您的代码,看看它是否足够好。

回答by starblue

ConcurrentHashMap is optimized for concurrent access.

ConcurrentHashMap 针对并发访问进行了优化。

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.

访问不会锁定整个地图,而是使用更细粒度的策略,这提高了可扩展性。还有专门用于并发访问的功能增强,例如并发迭代器。

回答by eljenso

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

你是对的HashTable,你可以忘记它。

Your articlementions 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:

您的文章提到了一个事实,虽然 HashTable 和同步包装类通过一次只允许一个线程访问映射来提供基本的线程安全,但这不是“真正的”线程安全,因为许多复合操作仍然需要额外的同步,例如例子:

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 ConcurrentHashMapis a simple alternative for a HashMapwith a typical synchronizedblock as shown above. Read thisarticle to understand its intricacies better.

但是,不要认为这ConcurrentHashMap是具有如上所示HashMap典型synchronized块的a 的简单替代方案。阅读文章,了解其复杂性更好。

回答by Michael Borgwardt

The "scalability issues" for Hashtableare present in exactly the same way in Collections.synchronizedMap(Map)- they use very simple synchronization, which means that only one thread can access the map at the same time.

的“可扩展性问题”以Hashtable完全相同的方式存在Collections.synchronizedMap(Map)- 它们使用非常简单的同步,这意味着只有一个线程可以同时访问地图。

This is not much of an issue when you have simple inserts and lookups (unless you do it extremely intensively), but becomes a big problem when you need to iterate over the entire Map, which can take a long time for a large Map - while one thread does that, all others have to wait if they want to insert or lookup anything.

当您进行简单的插入和查找时,这不是什么大问题(除非您非常密集地进行),但是当您需要遍历整个 Map 时,这会成为一个大问题,这对于大型 Map 可能需要很长时间 - 而一个线程这样做,所有其他线程如果要插入或查找任何内容都必须等待。

The ConcurrentHashMapuses very sophisticated techniques to reduce the need for synchronization and allow parallel read access by multiple threads without synchronization and, more importantly, provides an Iteratorthat requires no synchronization and even allows the Map to be modified during interation (though it makes no guarantees whether or not elements that were inserted during iteration will be returned).

ConcurrentHashMap使用非常复杂的技术,以减少同步的需要,并允许由多个线程并行读取访问,而无需同步,更重要的是,提供了Iterator一个无需同步,甚至允许地图将互为作用时(修改虽然它不保证是否不会返回迭代期间插入的元素)。

回答by Kounavi

In general, if you want to use the ConcurrentHashMapmake sure you are ready to miss 'updates'
(i.e. printing contents of the HashMap does not ensure it will print the up-to-date Map) and use APIs like CyclicBarrierto ensure consistency across your program's lifecycle.

一般来说,如果你想使用ConcurrentHashMap确保你准备好错过“更新”
(即打印 HashMap 的内容并不能确保它会打印最新的 Map)并使用 APICyclicBarrier来确保你的程序的一致性生命周期。

回答by Raj

Here are few :

这里有几个:

1) ConcurrentHashMap locks only portion of Map but SynchronizedMap locks whole MAp.
2) ConcurrentHashMap has better performance over SynchronizedMap and more scalable.
3) In case of multiple reader and Single writer ConcurrentHashMap is best choice.

1) ConcurrentHashMap 只锁定 Map 的一部分,而 SynchronizedMap 锁定整个 MAp。
2) ConcurrentHashMap 比 SynchronizedMap 有更好的性能和更好的可扩展性。
3) 在多读者和单作者的情况下 ConcurrentHashMap 是最好的选择。

This text is from Difference between ConcurrentHashMap and hashtable in Java

本文来自Java ConcurrentHashMap 和 hashtable 的区别

回答by Satish

In ConcurrentHashMap, the lock is applied to a segment instead of an entire Map. Each segment manages its own internal hash table. The lock is applied only for update operations. Collections.synchronizedMap(Map)synchronizes the entire map.

在 中ConcurrentHashMap,锁定应用于一个段而不是整个 Map。每个段管理自己的内部哈希表。该锁仅适用于更新操作。Collections.synchronizedMap(Map)同步整个地图。

回答by Shivam Maharshi

  1. If Data Consistency is highly important - Use Hashtable or Collections.synchronizedMap(Map).
  2. If speed/performance is highly important and Data Updating can be compromised- Use ConcurrentHashMap.
  1. 如果数据一致性非常重要 - 使用 Hashtable 或 Collections.synchronizedMap(Map)。
  2. 如果速度/性能非常重要并且数据更新可能会受到影响 - 使用 ConcurrentHashMap。