使用wait/notify和不使用它们的同步块之间的区别是什么?

10 浏览
0 Comments

使用wait/notify和不使用它们的同步块之间的区别是什么?

如果我只使用synchronized,而不使用wait/notify方法,它仍然是线程安全的吗?有什么区别?

0
0 Comments

在这个问题上,我在一次面试中丢了脸,所以我决定再次查找并理解它,这已经是第十亿次了。

synchronized块使代码线程安全。这是毫无疑问的。当使用wait()notify()notifyAll()时,你正在尝试编写更高效的代码。例如,如果你有一个多个线程共享的项目列表,那么如果将其放在监视器的synchronized块中,那么线程将在上下文切换期间不断地跳入并运行代码,即使列表为空!

因此,wait()在监视器上(在synchronized(..)内部的对象)被用作一种机制,告诉所有线程放松下来,停止使用CPU周期,直到进一步通知或通知所有线程。

因此可以写出以下代码:

synchronized(monitor) {
    if( list.isEmpty() )
        monitor.wait();
}

...其他地方...

synchronized(monitor){
    list.add(stuff);
    monitor.notifyAll();
}

有一个规定,即在循环中始终调用wait(),例如while ( list.isEmpty() ) monitor.wait()如果你希望等待直到另一个线程在列表中放入了实际的内容。docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()

这应该是答案。程序员不能选择哪个synchronized块应该先执行。但是wait()notify()可以指导哪个块应该先执行。+1。

如果一个线程已经获取了监视器的锁并正在使用它,那么第二个线程如何获取监视器的锁以进入synchronized块并等待呢?

每个线程都在“等待”自己。当锁的持有者调用wait()时,它会释放此锁。因此,争夺进入synchronized块的另一个线程可以进入。

0
0 Comments

使用synchronized使得一个方法/块一次只能被一个线程访问。所以,是的,它是线程安全的。

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

那么为什么我们需要使用wait/notify方法呢?肯定有一些差异,对吗?

我认为当同步块结束时,它会释放锁。当执行同步方法或语句的其他线程无法获得锁时,它们将被阻塞。这也类似于wait()和notify()机制,非常相似。Alan正在询问有了wait()和notify()与仅仅普通的同步块结束相比有什么区别。

0
0 Comments

在Java中,将方法标记为synchronized有两个效果。首先,同一个对象上的两个同步方法的调用不可能交错执行。当一个线程执行一个对象的同步方法时,所有调用该对象的同步方法的其他线程都会阻塞(暂停执行),直到第一个线程完成该对象。其次,当同步方法退出时,它会自动与同一对象的任何后续同步方法调用建立happens-before关系。这确保了对对象状态的更改对所有线程可见。

synchronized关键字帮助您保护关键代码。如果要在多个线程之间建立通信,必须使用wait()和notify()/notifyAll()。

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

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

notifyAll()方法唤醒等待该对象监视器的所有线程。线程通过调用wait方法等待对象的监视器。

wait()和notify()在以下情况下非常有用:生产者和消费者问题。消费者线程必须等待生产者线程产生数据。在上述情况下,wait()和notify()非常有用。随着时间的推移,引入了更好的替代方案。可以参考高级并发教程页面。

简而言之:

- 使用synchronized来保护关键部分的数据和代码。

- 如果要以安全的方式在多个线程之间建立通信,并且这些线程彼此之间是相互依赖的,请使用wait()和notify()与synchronized一起使用。

相关问题:

- [What does 'synchronized' mean?](https://stackoverflow.com/questions/1085709)

- [A simple scenario using wait() and notify() in java](https://stackoverflow.com/questions/2536692)

0