IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> ConcurrentHashMap常见的问题 -> 正文阅读

[数据结构与算法]ConcurrentHashMap常见的问题

1.ConcurrentHashMap的实现原理
1.7 JDK7中的ConcurrentHashMap由Segment和HashEntry组成,即ConcurrentHashMap把哈希桶数组切分成小数组(Segment) , 每个小数组有n个HashEntry组成。将数据分为一段一段的存储,然后给每段数据配一 把锁,当一个线程占用锁访问其中一段数据时,其他段的数据
也能被其他线程访问,实现并发访问。

1.8 JDK8中的ConcurrentHashMap选择了与HashMap相同的Node数组+链表+红黑树结构在锁的实现上,抛弃了原有的Segment分段锁,采用CAS + synchronized实现更加细粒度的锁。将锁的级别控制在了更细粒度的哈希桶数组元素级别,只需要锁住这个链表头节点(红黑树的根节点),就不会影响其他的哈希桶数组元素的读写,大大提高了并发度。

2.ConcurrentHashMap的get方法是否要加锁
get方法不需要加锁。因为Node和HashEntry的元素value和指针next是用volatile 修饰的,在多线程环境下线程A修改节点的value或
者新增节点的时候是对线程B可见的。

3.ConcurrentHashMap不支持key或者value 为null 的原因
对于key不能为null,估计是作者不喜欢null的key的原因。
为什么value不能是null?
因为ConcorrentHashMap工作于多线程环境,如果ConcurrentHashMap.get(key)返回null, 就无法判断值是null,
还是没有该key;而单线程的HashMap却可以用containsKey(key)判断是否包含了这个key。

4.ConcurrentHashMap迭代器是强-致性还 是弱一致性
与HashMap迭代器是强一致性不同,ConcurrentHashMap 迭代器是弱一致性。
ConcurrentHashMap的迭代器创建后,就会按照哈希表结构遍历每个元素,但在遍历过程中,内部元素可能会发生变化,如果变化发生在已遍历过的部分,迭代器就不会反映出来,而如果变化发生在未遍历过的部分,迭代器就会发现并反映出来,这就是弱一致性。这样迭代器线程可以使用原来老的数据,而写线程也可以并发的完成改变,保证了多个线程并发执行的连续性和扩展性,是性能提升的关键。

5.JDK7与JDK8中ConcurrentHashMap 的区别
底层数据结构: JDK7底层 数据结构是使用Segment组织的数组+链表,JDK8中取而代之的是数组+链表+红黑树的结构,在链表节点数量大于8 (且数据总量大于等于64)时,会将链表转化为红黑树进行存储。查询时间复杂度:从JDK7的遍历链表0(n), JDK8 变成遍历红黑树O(logN)。保证线程安全机制: JDK7 采用Segment的分段锁机制实现线程安全,其中Segment继承自ReentrantLock。JDK8采用CAS+synchronized保证线程安全。锁的粒度: JDK7 是对需要进行数据操作的Segment加锁,JDK8 调整为对每个数组元素的头节点加锁。

7.JDK8中为什么使用synchronized替换ReentrantLock
synchronized性能提升,在JDK6中对synchronized锁的实现引入了大量的优化,会从无锁->偏向锁->轻量级锁->重量级锁一步步转换就是锁膨胀的优化。以及有锁的粗化锁消除自适应自旋等优化。提升并发度和减少内存开销,CAS + synchronized方式时加锁的对象是每个链条的头结点,相对Segment再次提高了并发度。如果使用可重入锁达到同样的效果,则需要大量继承自ReentrantL ock的对象,造成巨大内存浪费。

8.ConcurrentHashMap的并发度如何设计的
并发度可以理解为程序运行时能够同时更新ConccurentHashMap且不产生锁竞争的最大线程数。在JDK7中,实际上就ConcurrentHashMap中的分段锁个数,即Segment]的数组长度, 默认是16,这个值可以在构造函数中设置。如果自己设置了并发度,ConcurrentHashMap 会使用大于等于该值的最小的2的幂指数作为实际并发度。如果并发度设置的过小,会带来严重的锁竞争问题;如果并发度设置的过大,原本位于同一个Segment内的访问会扩散到不同的Segment中,从而引起程序性能下降。在JDK8中,已经摒弃了Segment的概念,选择了Node数组t链表+红黑树结构,并发度大小依赖于数组的大小。

9.ConcurrentHashMap和Hashtable的效率哪个更高
ConcurrentHashMap的效率要高于Hashtable
因为Hashtable给整个哈希表加锁从而实现线程安全。而ConcurrentHashMap的锁粒度更低:在JDK7中采用Segment锁(分段锁)实现线程安全
在JDK8中采用CAS+synchronized实现线程安全。

10.多线程下安全的操作Map还有其它方法吗?
可以使用Collections.synchronizedMap(Map类型的对象)方法进行加同步锁。把对象转换成SynchronizedMap<K, V>类型如果传入的是HashMap对象,其实也是对HashMap做的方法做了一层包装,里面使用对象锁来保证多线程场景下,线程安全,本质也是对HashMap进行全表锁。在竞争激烈的多线程环境下性能依然也非常差,不推荐使用

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 19:19:22  更:2022-06-29 19:23:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/25 10:03:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码