同步块与等待/通知和没有它们之间的区别?

Ala*_*lan 18 java multithreading synchronized notify wait

如果我只使用synchronized,而不是wait/notify方法,它是否仍然保持线程安全?

有什么不同 ?

Thx提前.

Boz*_*zho 13

使用synchronized一次只能在线程上访问方法/块.所以,是的,它是线程安全的.

这两个概念结合在一起,而不是相互排斥.使用时,wait()您需要拥有该对象上的监视器.所以你需要synchronized(..)在此之前拥有它.使用.wait()使当前线程停止,直到另一个线程调用.notify()它等待的对象.这是一个补充synchronized,只是确保只有一个线程将进入块/方法.

  • 我认为,当同步块结束时,它将释放锁定。其他执行同步方法或语句的线程将在无法获取锁时阻塞。它也像一个wait()notify()机制,非常相似。艾伦(Alan)在问,拥有wait()和notify()与普通的同步块结束有什么区别? (3认同)
  • 那么为什么我们需要使用等待/通知方法呢?一定有一些不同,对吧? (2认同)

Ara*_*rif 10

因此,在对此采访的一个问题上感到尴尬之后,我决定再次查看它并再次理解它第十亿次.

synchronized块使代码线程安全.毫无疑问.当wait()和notify()或notifyAll()进来时,你试图编写更有效的代码.例如,如果您有多个线程共享的项目列表,那么如果您将它放在监视器的synchronized块中,那么线程线程将不断地跳入并在上下文切换期间来回运行代码,返回和堡垒..... .甚至有一个空列表!

因此,wait()用于监视器(synchronized(..)中的对象)作为一种机制,告诉所有线程放松并停止使用cpu循环,直到另行通知或notifyAll().

像这样的东西:

synchronized(monitor) {
    if( list.isEmpty() )
        monitor.wait();
}
Run Code Online (Sandbox Code Playgroud)

  • 它规定你总是在循环中调用 wait() ,例如 while ( list.isEmpty() ) monitor.wait() 如果你想等到另一个线程实际放入列表中的东西。https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait() (2认同)

Rav*_*abu 5

同步方法 有两个作用:

首先,对同一对象的同步方法的两次调用不可能交错。当一个线程正在为一个对象执行同步方法时,所有其他调用同一个对象的同步方法的线程都会阻塞(挂起执行),直到第一个线程完成对对象的处理

其次,当一个同步方法退出时,它会自动建立一个发生在同一个对象的同步方法的任何后续调用之前的关系。这保证了对象状态的更改对所有线程都是可见的。

同步帮助您保护关键代码。

如果要在多个线程之间建立通信,必须使用wait()notify() / notifyAll()

wait():使当前线程等待,直到另一个线程为此对象调用notify() 方法或notifyAll() 方法。

notify(): 唤醒在此对象的监视器上等待的单个线程。如果有任何线程正在等待该对象,则选择其中一个线程被唤醒。

notifyAll():唤醒在此对象监视器上等待的所有线程。线程通过调用等待方法之一在对象的监视器上等待。

使用 wait() 和 notify() 的简单用例:生产者和消费者问题

消费者线程必须等到生产者线程产生数据。wait() 和 notify() 在上述场景中很有用。在一段时间内,已经引入了更好的替代方案。请参阅此高级并发教程页面。

简单来说:

用于synchronized保护数据的关键部分并保护您的代码。

如果要以安全的方式在相互依赖的多个线程之间建立通信,请使用wait()notify()与同步一起使用。

相关 SE 问题:

“同步”是什么意思?

java中使用wait()和notify()的简单场景