Java 使用wait和notify时避免死锁
首先,我知道这个问题以前好像有人问过,但我没有得到任何好的答案,所以我会再问得更清楚一些 如果通知在当前没有其他线程等待时发生,则此代码可能会导致死锁Java 使用wait和notify时避免死锁,java,multithreading,concurrency,synchronization,deadlock,Java,Multithreading,Concurrency,Synchronization,Deadlock,首先,我知道这个问题以前好像有人问过,但我没有得到任何好的答案,所以我会再问得更清楚一些 如果通知在当前没有其他线程等待时发生,则此代码可能会导致死锁 while (!checkPreConditions()){ synchronized(lock){ lock.wait(); } } doWork(); synchronized(lock) { lock.notifyAll(); } 我尝试在没有线程等待时为通知的线程数设置一个
while (!checkPreConditions()){
synchronized(lock){
lock.wait();
}
}
doWork();
synchronized(lock) {
lock.notifyAll();
}
我尝试在没有线程等待时为通知的线程数设置一个计数器,但是这个解决方案有点麻烦。。
另一个想法是让等待超时,但程序可能会无缘无故地等待。这个问题有共同的解决方案/模式吗 我认为您试图使用一个过于简单的工具(
synchronized
)来解决一个稍微复杂一点的问题。您应该阅读java并发包提供的更高级别的并发实用程序类
最有可能的是,a将为您完成这项工作,因为对于信号量,获取和释放锁定机制的顺序并不重要。也就是说,使用信号量,您可以在获取之前释放。我认为您试图使用一个过于简单的工具(
同步的
)来解决稍微复杂一点的问题。您应该阅读java并发包提供的更高级别的并发实用程序类
最有可能的是,a将为您完成这项工作,因为对于信号量,获取和释放锁定机制的顺序并不重要。也就是说,使用信号量,您可以在获取之前释放。我认为您试图使用一个过于简单的工具(
同步的
)来解决稍微复杂一点的问题。您应该阅读java并发包提供的更高级别的并发实用程序类
最有可能的是,a将为您完成这项工作,因为对于信号量,获取和释放锁定机制的顺序并不重要。也就是说,使用信号量,您可以在获取之前释放。我认为您试图使用一个过于简单的工具(
同步的
)来解决稍微复杂一点的问题。您应该阅读java并发包提供的更高级别的并发实用程序类
最有可能的是,a将为您完成这项工作,因为对于信号量,获取和释放锁定机制的顺序并不重要。也就是说,使用信号量,您可以在获取之前释放。如果我正确理解了这个问题,我认为您所说的是“虚假唤醒”场景。 最好的解决方案在“Object.java”javadoc中给出:) 以下是java文档的片段:
* A thread can also wake up without being notified, interrupted, or
* timing out, a so-called <i>spurious wakeup</i>. While this will rarely
* occur in practice, applications must guard against it by testing for
* the condition that should have caused the thread to be awakened, and
* continuing to wait if the condition is not satisfied. In other words,
* waits should always occur in loops, like this one:
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
*线程也可以在不被通知、中断或删除的情况下唤醒
*超时,所谓的虚假唤醒。虽然这很少会发生
*在实践中,应用程序必须通过测试
*导致线程被唤醒的条件,以及
*如果条件不满足,则继续等待。换句话说,,
*等待应始终在循环中发生,如下所示:
*
*同步(obj){
*而()
*对象等待(超时);
*…//执行适合条件的操作
* }
*
希望这有帮助。有关更多详细信息,请参见此
若我正确理解了这个问题,我想你们说的是“虚假唤醒”场景。 最好的解决方案在“Object.java”javadoc中给出:) 以下是java文档的片段:
* A thread can also wake up without being notified, interrupted, or
* timing out, a so-called <i>spurious wakeup</i>. While this will rarely
* occur in practice, applications must guard against it by testing for
* the condition that should have caused the thread to be awakened, and
* continuing to wait if the condition is not satisfied. In other words,
* waits should always occur in loops, like this one:
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
*线程也可以在不被通知、中断或删除的情况下唤醒
*超时,所谓的虚假唤醒。虽然这很少会发生
*在实践中,应用程序必须通过测试
*导致线程被唤醒的条件,以及
*如果条件不满足,则继续等待。换句话说,,
*等待应始终在循环中发生,如下所示:
*
*同步(obj){
*而()
*对象等待(超时);
*…//执行适合条件的操作
* }
*
希望这有帮助。有关更多详细信息,请参见此
若我正确理解了这个问题,我想你们说的是“虚假唤醒”场景。 最好的解决方案在“Object.java”javadoc中给出:) 以下是java文档的片段:
* A thread can also wake up without being notified, interrupted, or
* timing out, a so-called <i>spurious wakeup</i>. While this will rarely
* occur in practice, applications must guard against it by testing for
* the condition that should have caused the thread to be awakened, and
* continuing to wait if the condition is not satisfied. In other words,
* waits should always occur in loops, like this one:
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
*线程也可以在不被通知、中断或删除的情况下唤醒
*超时,所谓的虚假唤醒。虽然这很少会发生
*在实践中,应用程序必须通过测试
*导致线程被唤醒的条件,以及
*如果条件不满足,则继续等待。换句话说,,
*等待应始终在循环中发生,如下所示:
*
*同步(obj){
*而()
*对象等待(超时);
*…//执行适合条件的操作
* }
*
希望这有帮助。有关更多详细信息,请参见此
若我正确理解了这个问题,我想你们说的是“虚假唤醒”场景。 最好的解决方案在“Object.java”javadoc中给出:) 以下是java文档的片段:
* A thread can also wake up without being notified, interrupted, or
* timing out, a so-called <i>spurious wakeup</i>. While this will rarely
* occur in practice, applications must guard against it by testing for
* the condition that should have caused the thread to be awakened, and
* continuing to wait if the condition is not satisfied. In other words,
* waits should always occur in loops, like this one:
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
*线程也可以在不被通知、中断或删除的情况下唤醒
*超时,所谓的虚假唤醒。虽然这很少会发生
*在实践中,应用程序必须通过测试
*导致线程被唤醒的条件,以及
*如果条件不满足,则继续等待。换句话说,,
*等待应始终在循环中发生,如下所示:
*
*同步(obj){
*而()
*对象等待(超时);
*…//执行适合条件的操作
* }
*
希望这有帮助。有关更多详细信息,请参见此