Java 如果将单个线程调度到多个核上,则会对内存可见性产生影响

Java 如果将单个线程调度到多个核上,则会对内存可见性产生影响,java,multithreading,scheduling,multicore,cpu-cache,Java,Multithreading,Scheduling,Multicore,Cpu Cache,这个问题是关于JVM的&内存可见性保证 假设我有一个线程t1,它访问堆上的变量,比如x 假设线程计划在内核c1中执行,并且在寄存器中修改了x(从RAM中提取后),并且x必须从寄存器中移出,因为t1需要执行更多的指令,这些指令需要将额外的数据加载到寄存器中。因此实际上,x位于c1s缓存中,而不是寄存器中 现在,操作系统将另一个线程t2调度到c1,因此cpu寄存器中充满了新数据,但我们的缓存中仍有x的容量(实际上,我暗示缓存可能没有刷新到RAM/L3。这是我的假设,不确定是否确实如此) 一段时间后,

这个问题是关于JVM的&内存可见性保证

假设我有一个线程
t1
,它访问堆上的变量,比如
x

假设线程计划在内核
c1
中执行,并且在寄存器中修改了
x
(从RAM中提取后),并且
x
必须从寄存器中移出,因为
t1
需要执行更多的指令,这些指令需要将额外的数据加载到寄存器中。因此实际上,
x
位于
c1
s缓存中,而不是寄存器中

现在,操作系统将另一个线程
t2
调度到
c1
,因此cpu寄存器中充满了新数据,但我们的缓存中仍有
x
的容量(实际上,我暗示缓存可能没有刷新到RAM/L3。这是我的假设,不确定是否确实如此)

一段时间后,操作系统将原始
t1
线程调度到新的内核
c2
,是否仍然需要
t1
才能在所有情况下查看
c1
s缓存中
x
的最新值

如果
c2
中的
t1
没有在
c1
中看到最新的
x
,我相信我们将违反JMM的顺序一致性

我错了吗

PS:我已经读过另一篇关于相同/类似问题的文章,但它没有解决我满意的问题。所以把它重新放在这里


只是不要担心缓存相关的不一致性。JMM对您隐藏所有特定于硬件的内存模型详细信息。因此,从JMM的角度来看,坚持这一点并避免竞争条件就足够了

如果您关心这些低级细节,那么对于x86,您可能需要阅读《英特尔手册》第3A卷第8章:

这些多处理机制具有以下特点 特点:

[……]

•保持缓存一致性-当一个处理器访问 缓存在另一个处理器上的数据,它不能 接收不正确的数据。如果它修改数据,则所有其他处理器 访问该数据必须接收修改后的数据

[……]


这应该足够令人信服,至少在x86上不必担心缓存不一致:)

Java规范说“线程中的每个操作都发生在该线程中的每个操作之前,该线程中的每个操作都是按照程序的顺序来的。”(请参阅)。因此JVM保证您所描述的不会发生。“如果c2中的t1没有看到c1中最新的x…”缓存一致性协议确保在缓存中修改is
x
,其他缓存不能看到过时的值。@jbnize,您的注释应该是一个答案。