Java ConcurrentHashMap在内部是如何工作的?
我正在阅读有关Java并发性的Oracle官方文档,我想知道Java ConcurrentHashMap在内部是如何工作的?,java,collections,concurrency,hashmap,Java,Collections,Concurrency,Hashmap,我正在阅读有关Java并发性的Oracle官方文档,我想知道 public static <T> Collection<T> synchronizedCollection(Collection<T> c); 公共静态集合synchronizedCollection(集合c); 例如,使用 ConcurrentHashMap。我假设我在HashMap上使用synchronizedCollection(Collection c)。我知道,一般来说,同步集合本质
public static <T> Collection<T> synchronizedCollection(Collection<T> c);
公共静态集合synchronizedCollection(集合c);
例如,使用
ConcurrentHashMap
。我假设我在HashMap
上使用synchronizedCollection(Collection c)
。我知道,一般来说,同步集合本质上只是我的HashMap
的装饰器,因此ConcurrentHashMap
的内部显然有些不同。您有关于这些实施细节的一些信息吗
编辑:我意识到源代码是公开的:
synchronizedCollection()返回的对象是一个对象,其所有方法都在此对象上同步,因此此类包装器上的所有并发操作都是序列化的。ConcurrentHashMap是一个真正的并发容器,它具有细粒度的锁,优化了锁以尽可能降低争用。查看源代码,您将看到它的内部内容。ConcurrentHashMap与
java.util.HashTable
类非常相似,只是ConcurrentHashMap
提供了比HashTable
或synchronizedMap
更好的并发性ConcurrentHashMap
在读取地图时不会锁定地图。此外,ConcurrentHashMap
在写入时不会锁定整个Map
。它仅在内部锁定正在写入的映射的部分
另一个区别是,如果ConcurrentHashMap
在迭代过程中发生更改,则ConcurrentHashMap不会抛出ConcurrentModificationException
。虽然迭代器
的设计不允许多个线程使用,但是synchronizedMap
可能会抛出ConcurrentModificationException
我会阅读,因为它的细节相当复杂。简言之,它已经做到了
- 可以独立锁定的多个分区。(默认情况下为16)
- 使用并发锁操作实现线程安全,而不是同步
- 具有线程安全迭代器。synchronizedCollection的迭代器不是线程安全的
- 不会暴露内部锁。synchronizedCollection没有
这篇文章帮助我理解了它
Hashtable提供对其条目的并发访问,但有一点需要注意,整个映射被锁定以执行任何类型的操作。
而这种开销在正常情况下在web应用程序中是可以忽略的
负载,在重负载下,可能导致响应时间延迟和
没有正当理由使服务器负担过重
这就是ConcurrentHashMap的切入点。它们提供了所有的功能
Hashtable的性能几乎与HashMap一样好。
ConcurrentHashMap通过一个非常简单的机制来实现这一点。
集合维护的列表不是地图范围的锁,而是16个
默认情况下锁定,每个用于保护(或锁定)单个
一桶地图。这实际上意味着16个线程可以修改
在同一时间收集(只要他们都在工作
不同的桶)。事实上,没有通过此操作执行任何操作
锁定整个地图的集合。的并发级别
集合,可以同时修改它的线程数
没有阻塞,可以增加。然而,数字越高意味着更多
维护此锁列表的开销
哈希表
的“可伸缩性问题”在集合中以完全相同的方式出现。synchronizedMap(Map)
-它们使用非常简单的同步,这意味着只有一个线程可以同时访问Map
当您进行简单的插入和查找时,这不是什么大问题(除非您进行了非常密集的插入和查找),但当您需要迭代整个映射时,这会成为一个大问题,对于一个大型映射,这可能需要很长的时间-当一个线程执行此操作时,所有其他线程都必须等待,如果他们想要插入或查找任何内容
ConcurrentHashMap
使用非常复杂的技术来减少同步需求,允许多线程在不同步的情况下进行并行读取访问,更重要的是,它提供了一个不需要同步的迭代器,甚至允许在交互过程中修改映射(尽管它不能保证在迭代过程中插入的元素是否会被返回)。ConcurrentHashMap实现了提供并发性的ConcurrentMap。
Deep内部的迭代器设计为一次只能由一个线程使用,以保持同步。
此映射在并发中被广泛使用。IMHO这是每个java开发人员都应该阅读的书籍之一:-)@PeterLawrey-seconded。投票赞成改正我也不明白他为什么投票反对你。我也投票支持你。为那些没有JDK的人提供一个到源代码的链接会很有用,IDE或谷歌访问我会添加一个链接。。)我刚刚意识到源代码对我来说是可用的。我看到CHM有自己的用于锁定的ReentrantLock子类。谢谢你的信息!是的,每个分区一个段。您可以增加分区的数量,但很少需要(除了一些微基准测试;)分区您指的是存储桶?或者这不是用经典的桶+链表模型实现的?链接已经失效,但是@LaurentBourgault Roy,cheers编辑的答案反映了这一点