美文网首页
ConcurrentHashMap学习

ConcurrentHashMap学习

作者: 盼旺 | 来源:发表于2019-09-21 14:00 被阅读0次

结构模型


与HashMap不同的是,ConcurrentHashMap中多了一层数组结构
ConcurrentHashMap类中包含两个静态内部类 HashEntrySegmentHashEntry 用来封装映射表的键 / 值对;Segment 用来充当锁的角色,每个 Segment 对象守护整个散列映射表的若干个桶。每个桶是由若干个 HashEntry 对象链接起来的链表。一个 ConcurrentHashMap实例中包含由若干个 Segment对象组成的数组

ConcurrentHashMap 在默认并发级别会创建包含 16个 Segment 对象的数组。每个 Segment 的成员对象 table 包含若干个散列表的桶。每个桶是由 HashEntry 链接起来的一个链表。如果键能均匀散列,每个 Segment 大约守护整个散列表中桶总数的 1/16。

ConcurrentHashMap 的结构示意图:

用分离锁实现多个线程间的并发写操作

这里的加锁操作是针对(键的 hash 值对应的)某个具体的 Segment,锁定的是该 Segment 而不是整个 ConcurrentHashMap。

用 Volatile 变量协调读写线程间的内存可见性

这点成就了:读线程在读取散列表时,基本不需要加锁
由于内存可见性问题,未正确同步的情况下,写线程写入的值可能并不为后续的读线程可见。


只要之前对链表做结构性修改操作的写线程 M 在退出写方法前写 volatile 型变量 count,读线程 N 在读取这个 volatile 型变量 count 后,就一定能“看到”这些修改。所以读线程在读取散列表时,基本不需要加锁就能成功获得需要的值

总结

在使用锁来协调多线程间并发访问的模式下,减小对锁的竞争可以有效提高并发性。有两种方式可以减小对锁的竞争:

  • 减小请求 同一个锁的 频率。
  • 减少持有锁的 时间。

ConcurrentHashMap 的高并发性主要来自于三个方面:

  • 用分离锁实现多个线程间的更深层次的共享访问。使用分离锁,减小了请求同一个锁的频率。
  • 通过 HashEntery 对象的不变性及对同一个 Volatile 变量的读 / 写来协调内存可见性,使得读操作大多数时候不需要加锁就能成功获取到需要的值。
  • 通过对同一个 Volatile 变量的写 / 读访问,协调不同线程间读 / 写操作的内存可见性。

参考文章探索 ConcurrentHashMap 高并发性的实现机制

相关文章

网友评论

      本文标题:ConcurrentHashMap学习

      本文链接:https://www.haomeiwen.com/subject/dhfeuctx.html