之前可能已经回答过,但由于问题的复杂性,我需要确认。所以我重新解释了这个问题
问题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 :线程1中的object.field1 = "";
隐含地是发生在之前关系的一部分吗?
我希望是,但可能没有。如果不是,有一个技巧,使它没有把它放入同步块?否则很难在程序上推理 将所有内容置于同步{}。
之下是不切实际的编辑:澄清:object.field1不易变,问题是"线程2保证看到线程1的写入,至少"。我的问题是内存可见性。为了论证,让我们说只有线程1写入非易失性object.field1。
问题2可以改为为
"锁定推送上的同步块是否会在同一个锁上同步的其他线程看到之前发生变化? "
答案 0 :(得分:4)
1)当线程进入同步块时,内存屏障将包括所触及的任何字段,而不仅仅是我同步的对象的字段?
正确。 (假设线程1和线程2在同一个锁上同步。)
因此,如果在同步块中修改了许多对象,那么在线程内存缓存之间会有很多内存移动。
可能,是的。但是,它(可能)不是缓存之间的移动。更可能的是,它是从一个处理器的缓存到内存,从内存到第二个处理器缓存的移动。当然,这取决于硬件如何实现内存层次结构。
2)是object.field1 =“”;在线程1隐含地部分发生在之前的关系?
有一系列先发生过关系
object.field1
的写入。farAwayObject
之前发生这种情况。依此类推。object.field1
之前发生。如果在线程1获取object.field1
之前或者通过某个其他线程对lock
进行插入写入,则会出现问题。在任何一种情况下,before-before链不足以确保线程2看到线程1写入的值。
答案 1 :(得分:3)
当线程进入同步块时,内存屏障将会出现 包括触摸的任何字段,而不仅仅是我对象的字段
同步
假设22
和farAwayObject
的字段始终通过在应用程序周围的同一对象上获取evenFarther
来修改和加入,所有线程将始终看到对lock
和farAwayObject
,因为evenFarther
强制发生在之前。
synchronized
//thread 2 guaranteed to see all fields above as ""
在不知道如何宣布的情况下也不能这样说。假设object.field1
是未标记为field1
的引用,它不会是在关系之前发生的一部分,并且线程可能会看到它的陈旧值。
我希望是,但可能没有。如果没有,那就有诀窍 没有把它放入同步块?
是。将volatile
标记为object.field1
。
添加您的修改:
问题2可以改为
"锁定上的同步块是否会在之前进行更改 其他线程看到在同一个锁上同步? "
AFAIK答案是肯定的,前提是写线程在读取线程之前获取锁定。不幸的是,这通常是您无法保证的,这就是为什么volatile
需要标记为object.field1
语句需要在volatile
块内移动的原因。< / p>
查看JSR 133,其中讨论了当线程退出 synchronized
块时刷新到主内存的缓存。这应该进一步澄清事情。
答案 2 :(得分:1)
内存屏障将包括所触及的任何字段,而不仅仅是我同步的对象的字段?
是
是object.field1 =&#34;&#34 ;;在线程1隐含地部分发生在之前的关系?
是的,即使它不是不稳定的。
之前发生的订单是部分订单。
发生之前的顺序是由与边缘和程序顺序同步的传递闭包给出的。它必须是有效的偏序:反身,传递和反对称。
同步边缘之前的操作(即同步锁定的释放)按程序顺序排序,因此与发布同步。传递性表示由另一个线程中的同一个锁的获取所排序的操作因此具有一个先前发生的命令,包括释放该锁和释放该锁之前的操作,无论是不是它在synchronized
块体内。要记住这一点的重要一点是,对动作(即获取/释放锁)的排序不是一个块,例如synchronized关键字的括号所隐含的。括号表示获取/释放操作的位置以及一组操作不能交错的位置。
最后,记住之前发生的事情是&#34;部分&#34;订购。这意味着:
synchronized
块之外。更强的订购保证也会在订购之前发生,但它们也提供了规范中描述的其他效果。