Java的同步会更新完整的缓存,还是只更新我同步的对象?

Fra*_*fka 10 java parallel-processing concurrency synchronization monitor

如果我访问同步方法或同步块内的对象,那个被访问元素中的所有对象是否也同步?

想象一下,有一个对象Queue具有同步add()take()方法,接受并分发复杂对象Thing.Thing有很多列表与其他不同的对象.

现在,图像线程Before创建Thing并放入一些现有对象Thing,修改其中一些对象,依此类推.该Before线增加ThingQueue.稍后一点线程After从中Thing获取Queue.

问题:Will Thing及其所有子/子对象是否处于Before离开它们的状态?即使线程After可能稍早在这些子元素中的一个上工作?因为我映像处理器的线程After可能仍然有一些关于该子元素的缓存信息(该子对象的地址仍然相同).只有通过Thing同步方式访问父对象,所有这些缓存的东西才会失效?

请不要给出使用并发库等的答案.我想了解发生了什么.

mus*_*iKk 9

如果一个线程修改了一个变量,那么另一个线程不能保证看到更改,除非在下列情况下(好吧,至少在以下情况下;我不是100%确定是否有更多):

  • 修改线程留下同步块或方法; 这会引起线程缓存的刷新(同样是进入同步块或方法的线程引起刷新) - 这就是你的情况
  • 声明修改后的变量,volatile或者它是来自的原子变量之一java.util.concurrent.atomic
  • 修改线程完成(这也会导致刷新,同样线程的开始会导致刷新)

因此,如果您按照说明进行同步,其他线程将看到所有更改.


Paŭ*_*ann 7

Java的内存模型中的重要概念是先前发生的顺序.读取操作之前发生的写入操作的结果对于这些读取操作是可见的.其他结果可能会或可能不会显示.

发生的,前顺序是由线程之间的同步行动,为了诱导,并通过自然的在各个线程的操作顺序.

如果你在Before一个对象(例如你的Queue)上进行同步,并Thing在这个synchronized-block内部或之前完成所有操作及其"子对象",并After在同步块上同步Queue并在同步块之后读取这些对象,那么所有这些变化都是可见的After.