当前位置: 首页 > 面试题库 >

Java:Java8开始ConcurrentHashMap,为什么舍弃分段锁?

樊杰
2023-04-24

ConcurrentHashMap的原理是引用了内部的 Segment ( ReentrantLock )  分段锁,保证在操作不同段 map 的时候, 可以并发执行, 操作同段 map 的时候,进行锁的竞争和等待。从而达到线程安全, 且效率大于 synchronized。

但是在 Java 8 之后, JDK 却弃用了这个策略,重新使用了 synchronized+CAS。

弃用原因

通过  JDK 的源码和官方文档看来, 他们认为的弃用分段锁的原因由以下几点:

加入多个分段锁浪费内存空间。
生产环境中, map 在放入时竞争同一个锁的概率非常小,分段锁反而会造成更新等操作的长时间等待。
为了提高 GC 的效率
新的同步方案

既然弃用了分段锁, 那么一定由新的线程安全方案, 我们来看看源码是怎么解决线程安全的呢?(源码保留了segment 代码, 但并没有使用)。

 类似资料:
  • discard关键字通常出现在片元着色器的if语句或for语句中,discard的使用语法就像for语句中的continue和break关键字一样,直接编写discard;即可,但是discard的功能比较特殊,专门用于着色器片元处理。 如果想理解discard,你首先应该建立逐片元的概念。GPU的片元着色器在逐个处理片元的过程中,会把不符合程序条件的代码舍弃掉。 discard一个代码案例 //

  • 问题内容: 为什么执行速度比切片慢? 令人惊讶的是,即使包括长度计算在内,切片仍然明显更快: 注意:此行为的第一部分已在 Python的数据分析 (第3章)中进行了说明,但未提供任何解释。 。 如果有帮助:这是;的C代码。这是输出: 问题答案: __可以通过考虑操作员完成工作所需的时间来解释 某些 性能差异: 差的另一部分可以通过以下事实来解释是一个 函数 ,和甚至无操作函数调用需要一点时间: 这

  • 我不断得到: debug.log 我的包文件如下: 我是npm的新手,当我第一次下载它时,我能够在我的本地服务器上毫无问题地启动它。 我想切换我的浏览器,这样做,突然npm start有一个问题。 我知道还有其他类似的问题,但没有一个能缓解我的问题。

  • 问题内容: 的JavaDoc 表示: 类似但不同,这个类就不会允许null用作键或值。 我的问题:为什么? 第二个问题:为什么Hashtable不允许null? 我已经使用了很多HashMaps来存储数据。但是,当更改为ConcurrentHashMap时,由于NullPointerExceptions我遇到了几次麻烦。 问题答案: ConcurrentMaps(ConcurrentHashMap

  • 问题内容: 嗨,我知道JDK 8之前的工作原理。我也理解了代码:它是模块化的,而且很难理解。 JDK 8中的代码与以前的实现相比已发生了很大变化。 由于此问题被归类为过于广泛,因此我现在将尝试非常具体。 CHMv8使用TreeBin(RedBlackTree的变体)存储桶,而不是使用链表。 所以我的问题是使用TreeBin而不是链接列表的主要优点是什么? 源代码在这里 问题答案: 主要更改是添加了

  • 当我阅读RISC-V用户级ISA手册时,我注意到它说“OpenRISC有条件代码和分支延迟槽,这使更高性能的实现变得复杂。”所以RISC-V没有分支延迟槽RISC-V用户级ISA手动链接。此外,维基百科说,大多数较新的RISC设计都省略了分支延迟槽。为什么大多数较新的RISC架构逐渐省略了分支延迟槽?