2 AtomicReferences can false share?

when i have

Object a;
Object b;

i have false sharing

this way i dont

@Contended
Object a;
Object b;

but if i have

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

do i still have false sharing?

my guess is that i dont need @Contended as although the a,b may be in the same cacheline what they refer to is not…

Instances of AtomicReference usually take 16 bytes (on HotSpot JVM): 12 bytes object header + 4 bytes value field. If two AtomicReferences lie next to each other in Java heap, they may still share the same cache line, which is typically 64 bytes.

Note: even if you allocate some object between two AtomicReferences, Garbage Collection may compact heap so that AtomicReferences are again located next to each other.

There are several ways to avoid false sharing:

  1. Extend AtomicReference class and add at least 6 long fields – this will make your references occupy 64 bytes or more.

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

  2. Use AtomicReferenceArray and place your references at the distance of at least 16 cells, e.g. one reference will be located at the index 16, and the other – at the index 32.

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