ConcurrentHashMap如何在内部工作?

Ada*_*old 43 java collections concurrency hashmap

我正在阅读关于Java中的并发的官方Oracle文档,我想知道Collection返回的有什么区别

public static <T> Collection<T> synchronizedCollection(Collection<T> c);
Run Code Online (Sandbox Code Playgroud)

并使用例如a

ConcurrentHashMap.我假设我用synchronizedCollection(Collection<T> c)的是HashMap.我知道一般来说,同步集合本质上只是我的装饰器HashMap所以很明显a ConcurrentHashMap的内部结构有所不同.您是否有关于这些实施细节的信息?

编辑:我意识到源代码是公开的: ConcurrentHashMap.java

Pet*_*rey 43

我会阅读ConcurrentHashMap源代码,因为它在细节上相当复杂.简而言之,它有

  • 可以独立锁定的多个分区.(默认为16)
  • 使用并发锁定操作来实现线程安全而不是同步.
  • 有线程安全的迭代器.synchronizedCollection的迭代器不是线程安全的.
  • 不暴露内部锁.synchronizedCollection确实如此.

  • 对于那些没有JDK,IDE或访问谷歌的人,我会添加一个链接.;) (9认同)

ami*_*ngh 22

ConcurrentHashMap是非常相似的java.util.HashTable类,但ConcurrentHashMap比提供了更好的并发HashTablesynchronizedMap做.ConcurrentHashMap在您阅读地图时不会锁定地图.此外,写入时ConcurrentHashMap不会锁定整个Map.它只在Map内部锁定正在写入的部分.

另一个区别是,ConcurrentModificationException如果在ConcurrentHashMap迭代时更改了ConcurrentHashMap,则不会抛出.在Iterator没有设计成由多个线程使用虽然,而synchronizedMap可能会引发ConcurrentModificationException

  • @downvoter评论通常比downvote更有用. (13认同)

gre*_*ude 15

这篇文章帮助我理解了为什么ConcurrentHashMap优于Hashtable并且和HashMap一样好

Hashtable提供对其条目的并发访问,只需要一个小警告,整个映射都被锁定以执行任何类型的操作.虽然这种开销在正常负载下的Web应用程序中是可忽略的,但在负载很重的情况下,它可能导致响应时间延迟和服务器过载,这是没有充分理由的.

这就是ConcurrentHashMap的步骤.它们提供了Hashtable的所有功能,其性能几乎与HashMap一样好.ConcurrentHashMap通过一种非常简单的机制实现了这一目标.该集合默认维护一个包含16个锁的列表,而不是地图宽锁,每个锁用于保护(或锁定)地图的单个存储桶.这实际上意味着16个线程可以一次修改集合(只要它们都在不同的桶上工作).事实上,此集合没有执行锁定整个地图的操作.可以增加集合的并发级别,可以在不阻塞的情况下同时修改它的线程数.但是,更高的数字意味着维护此锁列表的开销更大.

  • 链接已经死了,但是[它仍然可以通过返回机器访问](https://web.archive.org/web/20120321221256/http://www.codercorp.com/blog/java/why-concurrenthashmap-is - 更好的超哈希表和刚刚为好,hashmap.html) (3认同)

May*_*urB 5

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

当你有简单的插入和查找时(除非你非常密集地进行),这不是什么大问题,但是当你需要遍历整个Map时会出现一个大问题,这可能需要很长时间才能完成一个大的Map - 而一个线程就是这样做的,所有其他人都必须等待,如果他们想插入或查找任何东西.

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