为什么引用赋值在 Java 中是原子的?
据我所知,引用赋值在 64 位 JVM 中是原子的。现在,我假设jvm内部不使用原子指针来建模,因为否则就不需要原子引用。所以我的问题是:
在java / Scala的“规范”中,原子引用赋值是否保证会发生,或者它只是一个快乐的巧合,大多数时候都是这样?
对于任何编译为JVM字节码的语言(例如clojure,Groovy,JRuby,JPython...等) ?
如何在不使用原子指针的情况下,引用赋值是原子的?
据我所知,引用赋值在 64 位 JVM 中是原子的。现在,我假设jvm内部不使用原子指针来建模,因为否则就不需要原子引用。所以我的问题是:
在java / Scala的“规范”中,原子引用赋值是否保证会发生,或者它只是一个快乐的巧合,大多数时候都是这样?
对于任何编译为JVM字节码的语言(例如clojure,Groovy,JRuby,JPython...等) ?
如何在不使用原子指针的情况下,引用赋值是原子的?
首先,引用赋值是原子的,因为规范是这么说的。除此之外,JVM实现者没有障碍来满足这个约束,因为64位引用通常只用于64位架构,其中原子64位分配是免费的。
您主要的困惑源于这样一种假设,即由于其名称,附加的“原子引用”功能正是如此。但是,该类提供了更多功能,因为它封装了一个引用,该引用在多线程执行中具有更强的内存可见性保证。AtomicReference
volatile
具有原子引用更新并不一定意味着读取引用的线程还将看到有关可通过该引用访问的对象字段的一致值。它所保证的只是您将读取引用或对实际由某个线程存储的现有对象的有效引用。如果需要更多保证,则需要同步、引用或 .null
volatile
AtomicReference
AtomicReference
还提供原子更新操作,如 或 。对于使用内置语言构造的普通引用变量,这些是不可能的(但仅适用于特殊类,如 or )。compareAndSet
getAndSet
AtomicReferenceFieldUpdater
VarHandle
原子引用赋值在规范中。
对引用的写入和读取始终是原子的,无论它们是作为 32 位值还是 64 位值实现的。
引自JSR-133:Java(TM)内存模型和线程规范,第12节非原子处理双和
长
,http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf。