java - 为什么在类 jsr166e.Striped64.Cell 中对值字段进行额外填充?

标签 java concurrency jvm

在作为 JSR166 的一部分引入的类中,作者使用所谓的填充来填充 Striped64.Cell 类的单值字段。

这是该类(class)的摘录:

/**
 * Padded variant of AtomicLong supporting only raw accesses plus CAS. The value field is placed
 * between pads, hoping that the JVM doesn't reorder them.
 * <p/>
 * JVM intrinsics note: It would be possible to use a release-only form of CAS here, if it were
 * provided.
 */
static final class Cell {
  volatile long p0, p1, p2, p3, p4, p5, p6;
  volatile long value;
  volatile long q0, q1, q2, q3, q4, q5, q6;

  ...

作者然后使用 CAS 以原子方式修改值。

在 Striped64 类中,作者还使用 Unsafe 访问另外两个字段,但没有应用任何此类填充。

我的问题是:为什么需要做这样的事情,引入 14 个冗余字段来填充单个值字段?

最佳答案

填充是为了防止共享 value 字段的缓存行 - 否则可能不得不从内存中重新获取值,因为缓存行上的其他内容需要整行无效。所以目标是提高性能。

为了让事情变得更简单,Java 8 引入了 @Contended annotation它在幕后做同样的事情,只是它是由 JVM 本身处理的。

关于java - 为什么在类 jsr166e.Striped64.Cell 中对值字段进行额外填充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22069423/

相关文章:

java - 如何在计算大量矩阵时使用内存

java - 使用 modeshape 在 JCR 存储库中递归移动节点

java - 如何使用 Apache POI 锁定 docx 中图像的长宽比?

java - 在事务中运行 SELECT + UPDATE 与单独使用 UPDATE 有不同的结果吗?

java - ConcurrentLinkedQueue poll() 产生损坏的数据?

scala - 为什么我们需要 Future 和 Promise?

java - 无法使用 JPADatabase 从 H2 生成 Jooq 类

java - 为什么 ConcurrentHashMap.Segment 和 ConcurrentHashMap.HashEntry 类是静态的?

java - 为什么 JUnit "Run as->JUnit"和 "Cover as -> Junit"有不同的行为?

java - Jar-Exe转换后的文件执行