Java 在同步块中发生之前

发布于 2024-12-18 07:11:16 字数 734 浏览 2 评论 0原文

我需要一些帮助来理解 Java 内存模型。以下是一个掌握基本概念的通用示例:

Image 我有一个名为 Shared 的对象实例和两个线程 A 和 <代码>B。此外,还有某种带有同步 puttakeQueue

线程Aput方法之前之中修改Shared实例。

问题 1:当 B 通过同步 获取 Shared 对象实例时,A所有更改都可见>采用-方法?

问题 2:一旦 A 离开同步的 put 方法,内存缓存就会被刷新(Shared 上的所有更改都可见)。如果 Aput 方法中调用 wait() 会发生什么情况?即使 A 尚未退出 synchronized 方法,B 也会看到对 Shared 所做的更改吗?调用 wait() 时缓存是否也会被刷新?

I need some help understanding the Java memory model.The following is a gerneric example to grasp the basic concept:

Image I have an object instance called Shared and two threads A and B. Furthermore there is some kind of Queue with a synchronized put and take.

Thread A modifies the Shared-instance before and in the put method.

Question 1: All changes from A are visible when B gets the Shared-object instance through the synchronized take-method?

Question 2: The memory cache is flushed (all changes on Shared are visible) as soon as A leaves the synchronized put-method. What exaclty happens if wait() is called in the put-method by A? Will B also see the changes done to Shared even though A hasn't yet exited the synchronized-method? Is the cache also flushed when calling wait()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

君勿笑 2024-12-25 07:11:16

答案1:是的。因为 take() 和 put() 都是同步的。因此,在 B 执行 take() 之前,A 应该已经离开同步块,而离开同步块意味着刷新内存缓存(内存栅栏/屏障)。

答案2:是的。因为当调用wait()时,线程必须交出锁,这将再次导致内存刷新。

编辑:我认为您所追求的是缓存写入内存是否发生在同步块退出或释放锁时。答案是缓存写入内存发生在释放锁时

Answer 1: Yes. Because both take() and put() are synchronized. So before B could execute take(), A should have left the synchronized block and leaving the synchronized block means flushing memory cache(memory fence/barrier).

Answer 2: Yes. Because when wait() is called, the thread has to surrender the lock, which will again cause memory flushing.

EDIT: I think what you are after is that whether cache-write-to-memory happens on exit of synchronized block or release of lock. The answer is cache-write-to-memory happens on release of lock.

把梦留给海 2024-12-25 07:11:16

第一个问题的答案是肯定的,因为同步点(存在于 put 和 take 中)引入了隐式内存栅栏。

对于第二个问题,取决于 A 在将对象添加到 Shared 之前还是之后调用 wait。如果是之前,那么显然共享没有变化,因此 B 没有什么新的可看。

编辑:如果 A 在之后调用 wait,则更改是可见的,因为您必须在添加之前获取锁,然后在等待时释放它,这也会引入栅栏。

所以这两种情况的答案都是肯定的。

The answer to your first questions is Yes, because synchronization points (present in put and take) introduce implicit memory fences.

For the second question, it depends if A calls wait before or after the object is added to Shared. If it is before, then obviously there is no change to shared and so B has nothing new to see.

Edit: If A calls wait after, then the change is visible because you had to acquire a lock before adding and then release it when waiting which also introduces a fence.

So the answer is Yes in both cases.

蝶…霜飞 2024-12-25 07:11:16

A 尚未退出同步方法?调用 wait() 时缓存是否也被刷新?

引用自 JSR 133(Java 内存模型)常见问题解答 - 什么意思同步做什么?

退出同步块后,我们释放监视器,这具有将缓存刷新到主内存的作用,以便该线程所做的写入对其他线程可见。在进入同步块之前,我们获取监视器,这具有使本地处理器缓存无效的效果,以便从主内存重新加载变量。然后,我们将能够看到上一版本中可见的所有写入。

它说当监视器被释放时,会将缓存刷新到内存中。请注意,虽然监视器在退出同步块时被释放,但它也在调用 wait 方法时被释放。因此,我希望更改会在 #wait() 调用上刷新,并由另一个线程拾取,前提是它之前在同一监视器上等待。

A hasn't yet exited the synchronized-method? Is the cache also flushed when calling wait()?

Quoting from JSR 133 (Java Memory Model) FAQ - What does synchronization do? :

After we exit a synchronized block, we release the monitor, which has the effect of flushing the cache to main memory, so that writes made by this thread can be visible to other threads. Before we can enter a synchronized block, we acquire the monitor, which has the effect of invalidating the local processor cache so that variables will be reloaded from main memory. We will then be able to see all of the writes made visible by the previous release.

It says that flushing the cache to memory happens when a monitor is released. Note that while the monitor is released while exiting a synchronized block, it is also released while calling the wait method. So I'd expect the changes to be flushed on the #wait() call and to be picked up by the other thread provided it was waiting earlier on the same monitor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文