将Java';s同步更新整个缓存,还是仅更新我同步的对象?

将Java';s同步更新整个缓存,还是仅更新我同步的对象?,java,concurrency,synchronization,parallel-processing,monitor,Java,Concurrency,Synchronization,Parallel Processing,Monitor,如果我访问同步方法或同步块中的对象,那么被访问元素中的所有对象是否也同步 假设有一个对象队列拥有一个同步的add()和take()方法,接受并分发复杂的对象对象东西有很多列表,其中包含其他不同的对象 现在,前面的图像线程创建对象,并将一些现有对象放入对象,修改其中一些对象,依此类推。Before线程将Thing添加到队列中。稍晚一点之后的线程从队列获取内容 问题:Thing及其所有子对象/子对象是否会与保留它们之前的状态相同?即使之后的线程可能更早地处理这些子元素之一?因为我在之后为线程镜像处理

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

假设有一个对象
队列
拥有一个同步的
add()
take()
方法,接受并分发复杂的对象
对象
<代码>东西有很多列表,其中包含其他不同的对象

现在,前面的图像线程
创建
对象
,并将一些现有对象放入
对象
,修改其中一些对象,依此类推。
Before
线程将
Thing
添加到
队列中。稍晚一点
之后的线程从
队列
获取
内容

问题:
Thing
及其所有子对象/子对象是否会与
保留它们之前的状态相同?即使之后的线程可能更早地处理这些子元素之一?因为我在之后为线程镜像处理器可能仍然有一些关于该子元素的缓存信息(该子对象的地址仍然相同)。所有这些缓存的东西只有通过以同步方式访问父对象
Thing
才会失效


请不要给出诸如使用并发libs等答案。我想了解发生了什么。

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

  • 修改线程留下一个同步块或方法;这会导致线程缓存的刷新(类似地,进入同步块或方法的线程也会导致刷新)——这就是您的情况
  • 修改后的变量声明为
    volatile
    ,或者它是
    java.util.concurrent.atomic
  • 修改线程完成(这也会导致刷新,同样,线程的开始也会导致刷新)

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

Java内存模型中的重要概念是。读操作之前发生的写操作的结果对这些读操作可见。其他结果可能可见,也可能不可见

“先发生后发生”顺序是由线程之间动作的同步顺序以及各个线程中动作的自然顺序引起的


如果您在对象(例如,您的
队列
)上进行同步之前的
,并在此同步块内部或之前,以及在同一
队列
上进行同步之后的
,对
对象
及其“子对象”执行所有操作,并在同步块中或之后读取这些对象,然后所有这些更改在

之后对
可见是的,我知道,但这不是我的问题:-)同步还必须影响处理器缓存,以便将更改刷新到公共内存,这就是我的问题所在。我知道,如果你访问一个引用而不经过多个并行线程的同步块,它会把一切搞砸。但这更多的是关于将内容从一个线程传递到另一个线程,并确保数据结构仍然正确。明白我的意思吗?看保罗的答案。阻塞线程只是同步的一个方面,before关系(刷新缓存)即使不是更重要,也是同样重要的。理解起来也要困难得多,而且API不清楚以前发生过什么(例如,我认为SwingUtilities.invokeLater引发了一个以前发生过的事件,但我不是100%确定)。我强烈建议Goetz等人在实践中使用Java并发。他们非常强调“发生在之前”。感谢您在没有解释的情况下进行向下投票@弗兰兹:我不清楚你问的是记忆模型。让我重新考虑我的回答。@toto2:很公平。对我来说,这个问题听起来确实有些不同。我希望我现在就拿到了。:)