据我所知,引用分配在 64 位 JVM 中是原子的。 现在,我假设 jvm 内部不使用原子指针来对此进行建模,因为否则就不需要原子引用。所以我的问题是:
原子引用赋值在 java/Scala 的“规范”中并保证会发生,还是大多数时候都是这样,这只是一个令人高兴的巧合?
原子引用分配是否暗示任何编译为 JVM 字节码的语言(例如 clojure、Groovy、JRuby、JPython...等)?
在内部不使用原子指针的情况下,引用赋值如何能是原子的?
首先,引用分配是原子的,因为规范是这么说的。除此之外,JVM 实现者满足此约束没有任何障碍,因为 64 位引用通常仅在 64 位 架构上使用,其中原子 64 位分配是免费的。
您的主要困惑源于这样的假设:附加的“原子引用”功能正如其名称所示,正是这个意思。但是
AtomicReference
类提供了更多功能,因为它封装了 volatile
引用,在多线程执行中具有更强的内存可见性保证。
进行原子引用更新并不一定意味着读取该引用的线程也会看到有关通过该引用可访问的对象的“字段”的一致值。它保证的是您将读取 null
引用或对实际由某个线程存储的现有对象的有效引用。如果您想要更多保证,则需要诸如同步、
volatile
引用或AtomicReference
之类的构造。AtomicReference
还提供
原子更新操作,如
compareAndSet
或getAndSet
。对于使用内置语言构造的普通引用变量来说,这是不可能的(但仅限于像 AtomicReferenceFieldUpdater
或 VarHandle
这样的特殊类)。