java - Java 是否仅更改缓存中已修改字段的值?
问题描述
根据我的理解,当从缓存到主存发生回写时,它会写入整个缓存块。这可能包括未修改的字节/字,因为脏位是在整个缓存块上设置的。
在此,我假设 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
因为 C2a=1
在它的缓存中有而设置?
或者Java对此有任何保证吗?
假设没有建立之前/之后发生的关系。没有同步或易失性或其他类似的东西。
随时纠正我的任何假设。
解决方案
吹毛求疵:理论上写不需要去主存;根据所使用的缓存一致性算法,它们可以无限期地留在缓存中。
您所指的问题称为单词撕裂,JVM 应该防止它发生。
查看以下链接:
- https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.6
- https://shipilev.net/blog/2014/jmm-pragmatics/#_part_ii_word_tearing
我不熟悉其他架构,但在 X86 上,加载和存储可以在字节级别完成。一个 n 字节字段,将始终是 n 字节对齐的;所以它永远不会被分割成 2 个缓存行。由于 Java 中的布尔值存储在一个字节中,因此 X86 上不会发生字撕裂。
推荐阅读
- java - PathVariable 在 swagger SpringFox(3.0.0) 中作为可选
- ios - 在 Mac App Store 上下载应用程序时出现“找不到具有指定主机名的服务器”错误
- r - 如何在 dplyr summarise() 中排除 NA 值?
- python-3.x - 将 dict 转换为 numPy 数组
- python - 使用 Scrapy 递归地从 href 中提取文本
- r - pdfsearch "pdf 中无法识别的文本"
- python - 插入网页的音频文件没有采取行动,请在此处帮助我
- javascript - 确定字符串中的组
- mysql - 启用 innodb_dedicated_server 对性能有好处吗?
- java - 如何在 mac 上授予使用 jpackage 全盘访问权限打包的 java 应用程序?