java - 2 AtomicReferences可以虚假共享吗?

标签 java performance concurrency

当我有

Object a;
Object b;

我有虚假分享

这样我就不会

@Contended
Object a;
Object b;

但如果我有

final AtomicReference<Object> a;
final AtomicReference<Object> b;

我还有虚假分享吗?

我的猜测是我不需要@Contished,因为尽管a,b可能位于同一个缓存行中,但它们所指的不是...

最佳答案

AtomicReference 的实例通常需要 16 个字节(在 HotSpot JVM 上):12 个字节的对象头 + 4 个字节的值字段。如果两个 AtomicReference 在 Java 堆中彼此相邻,它们仍可能共享相同的缓存行,通常为 64 字节。

注意:即使您在两个 AtomicReference 之间分配一些对象,垃圾收集也可能会压缩堆,以便 AtomicReference 再次彼此相邻。

有几种方法可以避免错误共享:

  1. 扩展 AtomicReference 类并添加至少 6 个 long 字段 - 这将使您的引用占用 64 个字节或更多。

    -------------------------------------------------------------------------------
    | header | value | long1 | ... | long6 | header | value | long1 | ... | long6 |
    -------------------------------------------------------------------------------
                 ^                                      ^
                 |--------------- 64 bytes -------------|
    


  2. 使用 AtomicReferenceArray 并将引用放置在至少 16 个单元格的距离处,例如一个引用将位于索引 16,另一个引用位于索引 32。

    ----------------------------------------------------------------------------
    | header |  len  |  0  |  1  |  ...  |  15 |  16 |  17 |  ...  |  31 |  32 |
    ----------------------------------------------------------------------------
                                                  ^                         ^
                                                  |-------- 64 bytes -------|
    

关于java - 2 AtomicReferences可以虚假共享吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45347166/

相关文章:

Java - 重写 Comparable 的compareTo 方法后无法对用户定义的数组进行排序

c# - 从遗留类(启动方法 + 事件)创建任务(或可观察对象)

java - Hibernate 在 Spring Boot 1.4 开始时重命名了一些列

performance - 我应该相信 Redis 的数据完整性吗?

javascript - div的循环运动

java - 性能: ArrayList or ConcurrentHashMap

Java : Concurrent Modification exception when replacing pattern in ArrayList

java - 无法同步(java.util.ConcurrentModificationException)

java - Jenkins Ant 构建上的自定义 PMD 规则集文件不起作用

java - ViewPager 中替换 fragment 的问题