首先,类似于其他未命中信息的情况,例如:
Volatile 应该让线程从 RAM 中读取值
禁用线程缓存
更多关于为什么不是这样的细节可以在this SO thread找到。
这可以应用于语句:
JVM 还会从主目录重新读取对象的当前状态
进块时的内存
和
当同步块或方法退出时,JVM 会刷新任何
对象的修改状态回主存
引用 David Schwarz 在 cmets 中指出以下内容并允许我使用:
这在任何现代系统上都不会发生。这些是平台在理论上可能必须做的事情才能使同步工作,但如果它们在平台上不是必需的(并且它们不在您可能使用的任何平台上),它们还没有完成。
这些陈述都是关于没有硬件同步并且可能需要这些步骤的假设系统。 实际系统的硬件设计与这个简化的假设系统非常不同,需要完成的事情也大不相同。(例如,它们通常只需要优化和内存屏障,而不是刷新到主内存或读取。这是因为现代系统经过优化并使用缓存来避免必须刷新到主内存或从主内存重新读取,因为主内存非常慢,因此现代 CPU 有硬件优化来避免它。)
现在回到你的问题:
但是对于没有同步关键字的对象也是如此吗?所以在
CPU的一个核心中修改普通对象的情况是同步的
用主存让其他核心可以看到吗?
TL;DR:它可能会发生,也可能不会发生;它取决于硬件以及是否从缓存中读取对象;但是,通过使用synchronized,JVM 可以确保它会。
更详细的答案
所以如果是普通对象在CPU的一个核心被修改是
与主存同步,以便其他内核可以看到?
为了简单明了,没有同步它取决于将执行代码的硬件架构(例如缓存协议),并且取决于对象是否是(或不)在缓存中读取/更新。
如果架构强制核心中的数据始终与其他核心一致,那么可以。访问缓存比访问主存快得多,访问第一级缓存(例如,L1)也比访问其他级别快。
因此,出于性能原因,通常当从主内存加载数据(例如,对象)时,它会存储在缓存中(例如, L1、L2 , 和 L3) 以便在再次需要相同数据时更快地访问。
第一级缓存往往是每个内核私有的。因此,可能会发生不同的内核在其私有缓存(例如,L1)中存储了“相同对象”的不同状态。因此,线程也可能正在读取/更新“相同对象”的不同状态。
请注意,我写了 "same Object",因为从概念上讲它是同一个对象,但实际上它不是同一个实体,而是从 读取的同一个对象的副本主内存.