根据我的理解,当发生从缓存到主存的回写时,它会写整个缓存块。这可能包括未修改的字节/字,因为脏位设置在整个缓存块上。
在这里,我假设 CPU 架构通常不会在字节级别跟踪“脏”。如果所有目前的架构都在字节级别进行跟踪,请随时纠正我的假设。
比如说,两个 java 字段,比如说 a
和 b
并排存在并且具有相同的标签。因此,在缓存时,它们会被放置在同一个缓存块中。
假设有一个线程在内核中运行,它只更新 a
的值,而不更新 b
的值。那么,a
和 b
的值实际上会在主内存中从缓存中更新吗?
或者java有什么东西可以确保只有a
的值被更新,因为只有a
被改变了?
java 在这里也有作用吗?还是完全依赖于CPU架构?
我真正关心的
假设最初,a=1
,b=1
假设我们有两个线程 T1 和 T2。 T1 只做一件事,它设置 a=2
。类似地,T2 执行 b=2
。
假设我们有一个多核环境,内核 C1 和 C2 分别运行 T1 和 T2。两者都缓存值 a=1, b=1
。
说 T1 先完成。 C1 的缓存被写回。
所以,现在,在主存储器中,a=2, b=1
。
现在,T2 结束。现在当缓存被写回时,它是否设置了 a=1, b=2
因为 C2 在它的缓存中有 a=1
?
或者Java对此有任何保证吗?
假设没有 Happens Before/After 关系建立。没有同步或易失性或任何其他类似的东西。
请随时纠正我的任何假设。
答案 0 :(得分:1)
吹毛求疵:理论上写入不需要到主存;根据使用的缓存一致性算法,它们可以无限期地留在缓存中。
您所指的问题称为单词撕裂,JVM 应防止出现这种情况。
查看以下链接:
我不熟悉其他架构,但在 X86 上加载和存储可以在字节级别完成。一个 n 字节的字段,将始终是 n 字节对齐的;所以它永远不会被分成 2 个缓存行。由于 Java 中的布尔值存储在一个字节中,因此 X86 上不会发生字撕裂。