Java同步块中wait()方法对线程的影响

4
synchronized (lockObject) {
  // update some value of the common shared resource
  lockObject.wait();
}

在调用wait()方法时,线程将释放锁定,我想知道在释放锁定后它是否还会更新共享资源对象的主内存中的值,或者仅在同步块执行后才更新该值。


一旦执行了wait,其他线程可以看到在wait之前已经完成的工作。 - Burak Serdar
如果我们在同步块内运行代码,那么我们的代码将以互斥方式执行,这意味着一次只有一个线程将执行它,这意味着共享资源一次只能被一个线程访问,并且由于线程由处理器核心执行并将这些值缓存到它们的高速缓存中,因此当同步块的执行完成时,处理器仅更新这些值回到主内存以解决可见性问题。当我们调用wait()方法时,线程或处理器是否会将值更新到主内存? - Adarsh Verma
是的,wait 包括内存屏障。 - Burak Serdar
2个回答

4
由于现代CPU的缓存一致性协议,即使使用同步机制(例如synchronized或volatile),数据也不必写入主内存。现代CPU的缓存始终保持一致。
object.wait会导致线程释放锁。并且只要另一个线程发送了通知,锁就会被重新获取。在Java内存模型中,object.wait没有语义,只有锁的获取和释放是相关的。
因此,在您的特定情况下,如果一个线程执行wait,则会触发锁的释放。如果另一个线程在获取相同的锁之后读取该状态,则在执行锁释放(由于wait)的线程和获取锁的线程之间存在happens-before边缘。因此,第二个线程保证可以看到第一个线程的更改。

0
在JLS 17.4.5中提到:
“Object类(§17.2.1)的等待方法具有与之关联的锁定和解锁操作;它们的happens-before关系由这些关联操作定义。”
此外,根据JLS 17.4.4:
“对监视器m的解锁操作与随后对m上的所有锁定操作同步(其中“随后”根据同步顺序进行定义)。”
如果一个线程等待,它会放弃锁定,以便其他线程可以执行。因此,在等待之前线程所做的任何更改(触发解锁操作)应该对获取锁定的其他线程可见,这是很有意义的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接