在 Java 7 ConcurrentHashMap 中,为啥在写的时候需要段锁?为啥我们不能再次使用 Unsafe 来保持非阻塞?

Posted

技术标签:

【中文标题】在 Java 7 ConcurrentHashMap 中,为啥在写的时候需要段锁?为啥我们不能再次使用 Unsafe 来保持非阻塞?【英文标题】:In Java 7 ConcurrentHashMap, why segment lock is required while writing? Why can't we use Unsafe again to keep things non-blocking?在 Java 7 ConcurrentHashMap 中,为什么在写的时候需要段锁?为什么我们不能再次使用 Unsafe 来保持非阻塞? 【发布时间】:2016-09-20 18:09:05 【问题描述】:

在查看 Java 7 ConcurrentHashMap 的内部实现时,我注意到要设置新的 Segment,我们使用了 Unsafe 类,该类执行 Ordered 写入并利用比较和交换算法,从而支持非阻塞行为。

我的疑问是为什么 Concurrent HashMap 不使用比较和交换算法或类似的方法来保持对单链表的读写非阻塞,而不是获取段锁定然后写入单链表?

【问题讨论】:

【参考方案1】:

Unsafe 类中的方法通常使用起来不安全。仅当编写库的软件工程师发现由于其他限制而可以使用它们时,例如了解可能同时访问数据的内容,或了解如何在各种处理器架构上实现原语时,才会使用它们。

在这种情况下,Oracle 的一些工程师已经确定 Unsafe 类可用于段操作,但不能用于单链表。

【讨论】:

是的,我知道不应该首选 Unsafe 类,而是我们可以使用 AtomicReferenceArray 来完成同样的任务。不过,我想了解导致在段上使用锁定的限制是什么。 您应该尝试了解的是允许使用 Unsafe 类的异常情况。 实际上,在 ConcurrentHashMap 的文档中已经提到它用于降低间接级别,因为 AtomicReferenceArray 内部使用 Unsafe 来提供有序写入而不是易失性写入。此外,如果我的理解正确,它有助于避免易失性写入,这会产生内存屏障,从而导致性能稍好。如果我错了,请纠正我。

以上是关于在 Java 7 ConcurrentHashMap 中,为啥在写的时候需要段锁?为啥我们不能再次使用 Unsafe 来保持非阻塞?的主要内容,如果未能解决你的问题,请参考以下文章

java util - 在java代码中执行javascript代码工具 rhino-1.7.7.jar

Eclipse CVS extssh 在 Windows 7 + Java 7 下损坏

java 在Java中可被7整除

在 Windows 7 上信任 Java 7 的自签名证书

如何在 Windows (7) 上更改 Java 运行时版本?

在 Ubuntu 上安装 Java 7