java - 正在 64 位 VM 上编写引用原子

标签 java reference atomic memory-model

Java 内存模型要求编写 int是原子的:也就是说,如果您在一个线程中写入一个值(由 4 个字节组成)并在另一个线程中读取它,您将获得所有字节或没有,但永远不会获得 2 个新字节和 2 个旧字节等。

不保证 long .在这里,写 0x1122334455667788到变量持有0之前可能会导致另一个线程读取 0x1122334400000000x0000000055667788 .

现在规范不要求对象引用是 int 或 long-sized。出于类型安全的原因,我怀疑它们可以保证以原子方式编写,但在 64 位 VM 上,这些引用可能是非常好的 64 位值(仅仅是内存地址)。

现在是我的问题:

  • 是否有任何内存模型规范涵盖这一点(我还没有找到)?
  • 是否怀疑长写入在 64 位 VM 上是原子操作?
  • 虚拟机是否强制将引用映射到 32 位?

问候, 史蒂芬

最佳答案

读/写引用总是原子的

JLS section 17.7: Non-atomic Treatment of double and long

For the purposes of the Java programming language memory model, a single write to a non-volatile long or double value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64-bit value from one write, and the second 32 bits from another write.

Writes and reads of volatile long and double values are always atomic.

Writes to and reads of references are always atomic, regardless of whether they are implemented as 32-bit or 64-bit values.

Some implementations may find it convenient to divide a single write action on a 64-bit long or double value into two write actions on adjacent 32-bit values. For efficiency's sake, this behavior is implementation-specific; an implementation of the Java Virtual Machine is free to perform writes to long and double values atomically or in two parts.

Implementations of the Java Virtual Machine are encouraged to avoid splitting 64-bit values where possible. Programmers are encouraged to declare shared 64-bit values as volatile or synchronize their programs correctly to avoid possible complications.

(强调)

原子引用

如果您想在新旧值之间进行协调,或者想要 specific memory effects , 使用类 AtomicReference .

例如,AtomicReference::getAndSet在以原子方式设置新值的同时返回旧值,消除了另一个线程在两个步骤之间进行干预的任何机会。用途 volatile memory semantics .

关于java - 正在 64 位 VM 上编写引用原子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2576513/

相关文章:

java - 使用连续字符键的通用二分搜索失败

c++ - 分配对结构的引用

c# - 我应该使用什么来确保一段代码在 C# 中一起执行?

database - 使用 Paypal API 的原子性

java - 如何用char类型的单个字符替换字符串中的某些字符?

java - 如何延迟动画移动jlabel java swing?

java - 在 JSP 中显示包含 csv 数据的 java 对象的最佳方式?

arrays - 如何在 Swift 4 中引用数组内部数组的单元格?

java - 在 Java 中将内容从一个对象复制到另一个对象而无需具有相同的对象引用

multithreading - 如果系统是缓存一致的,您是否可以在固定到不同处理器的两个线程之间进行撕裂读/写?