这个问题之前可能已经得到解答,但由于问题的复杂性,我需要确认。所以我重新表述这个问题
问题1:当线程进入同步块时,内存屏障将包括所触及的任何字段,而不仅仅是我同步的对象的字段?因此,如果在同步块内修改许多对象,则会在线程内存缓存之间进行大量内存移动。
Thread 1
object.field1 = "";
synchronized (lock) {
farAwayObject.field1 = "";
farAwayObject.evenFarther.field2 = "";
}
Thread 2. assuming thread ordering is correct
synchronized (lock) {
//thread 2 guaranteed to see all fields above as ""
//even object.field1 ?
}
问题2 : Is object.field1 = "";
在线程 1 中隐含了发生之前关系的一部分?
我希望是这样,但也可能不是。如果不是,是否有技巧可以使其不放入同步块?否则很难对程序进行推理
将所有内容都放在同步的 { } 下是不切实际的。
编辑:澄清:object.field1 不是易失性的,问题是“线程 2 是否能保证至少看到线程 1 的写入”。我的问题是关于内存可见性。为了便于论证,假设只有线程 1 写入非易失性 object.field1。
问题2可以改写 as
“锁上的同步块是否会推送之前所做的更改,以便被在同一锁上同步的其他线程看到?”
1)当线程进入同步块时,内存屏障将包括所触及的任何字段,而不仅仅是我同步的对象的字段?
正确的。 (假设线程 1 和线程 2 在同一个锁上同步。)
因此,如果在同步块内修改许多对象,则会在线程内存缓存之间进行大量内存移动。
有可能,是的。然而,它(可能)不是缓存之间的移动。更有可能的是,它是从一个处理器的高速缓存到内存的移动,以及从内存到第二个处理器的高速缓存的移动。当然,这取决于硬件如何实现内存层次结构。
2) 是object.field1 = "";在线程 1 中隐含了发生之前关系的一部分?
存在一系列事前发生的关系
- 写入到
object.field1
发生在获取锁之前。
- 这发生在写入之前
farAwayObject
等等。
- 这发生在线程 1 释放锁之前
- 这发生在线程 2 获取锁之前
- 这发生在线程 2 读取之前
object.field1
.
问题是如果有中间写入会发生什么object.field1
,或者之前lock
由线程 1 或其他某个线程获取。在任何一种情况下,happens-before 链都不足以确保线程 2 看到线程 1 写入的值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)