首页 > 解决方案 > Java 是否仅更改缓存中已修改字段的值?

问题描述

根据我的理解,当从缓存到主存发生回写时,它会写入整个缓存块。这可能包括未修改的字节/字,因为脏位是在整个缓存块上设置的。

在此,我假设 CPU 架构通常不会在字节级别上跟踪“脏度”。如果所有当前架构都在字节级别上进行跟踪,请随时纠正我的假设。

说,两个java字段,说ab并排存在并且具有相同的标签。因此,在缓存时,它们将被放置在同一个缓存块中。

假设有一个线程在核心中运行,它只更新 的值a,但不更新b。那么,两者的值实际上会ab缓存中更新到主存中吗?或者 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因为 C2a=1在它的缓存中有而设置?

或者Java对此有任何保证吗?

假设没有建立之前/之后发生的关系。没有同步或易失性或其他类似的东西。

随时纠正我的任何假设。

标签: javacachingcpucpu-cache

解决方案


吹毛求疵:理论上写不需要去主存;根据所使用的缓存一致性算法,它们可以无限期地留在缓存中。

您所指的问题称为单词撕裂,JVM 应该防止它发生。

查看以下链接:

我不熟悉其他架构,但在 X86 上,加载和存储可以在字节级别完成。一个 n 字节字段,将始终是 n 字节对齐的;所以它永远不会被分割成 2 个缓存行。由于 Java 中的布尔值存储在一个字节中,因此 X86 上不会发生字撕裂。


推荐阅读