multithreading - JVM/x86 是否保证跨内核的值的非 volatile 传播?

标签 multithreading concurrency jvm java-memory-model

假设以下代码:

class X {
    private int v = 1;
    public void set(int v) { this.v = v; }
    public int get() { return v; }
}

是否有可能通过未将 v 标记为 volatile ,在调用 set(123) 时,其值不会传播到其他内核(即它们的缓存)和/或主内存),或者这只是时间问题?

通过询问,一般的想法似乎是迟早该值“会到达那里”,因此只要我们不太关心时间精度,就可以让该值保持非 volatile ,但我想正式确定。

我的理解是,由于没有获取/释放语义,JMM 不保证它能够工作,但另一方面,我对缓存一致性/一致性模型(即 TSO-x86)的(有限)理解是它最终必然会传播(将其标记为 volatile 只会设置一个栅栏以禁止在 CPU 的存储缓冲区中重新排序,但除此之外它最终会传播到其他缓存)。关于这一点,只有一点让我想知道——如果另一个核心向同一缓存行中的另一个变量写入内容会发生什么?在任何情况下它都能覆盖v吗?

任何了解此事的人都可以给我更具体的答案吗?

谢谢!

最佳答案

根据memory model JVM 中没有 happens-before你的例子中的关系。因此,从形式上讲,不能保证另一个线程会看到共享变量的更新。

依赖特定 JVM 和处理器架构的实现细节对我来说似乎不是一个好主意。今天在实验室有效的方法可能明天在现场就会失败。另请注意,最终可能会很长,因为没有上限。事实上,我遇到过这样的情况:我的程序似乎由于缺少 volatile 注释而被阻止,并且必须重新启动。

关于multithreading - JVM/x86 是否保证跨内核的值的非 volatile 传播?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56001665/

相关文章:

java - 线程只运行一次

c - 微 Controller 中的多线程

java - Java 是否提供一个 ExecutorService 允许一个 worker 在同一个线程上执行?

java - 强制 tableswitch 而不是 lookupswitch

clojure - 持久化 JVM 功能是如何在 cake 中实现的?

java - Spring 注入(inject)的 bean 线程安全

c++ - 尽管并行编译,Mex 文件还是串行执行

node.js - 如果业务逻辑执行时间过长(2000ms),nodeJS 如何处理并发请求

ios - 关于 Metal 中线程组内存的问题

java - 从核心转储中提取堆转储 (hprof)