gpt4 book ai didi

Java,等待并notifyAll : guard against spurious wakeups

转载 作者:行者123 更新时间:2023-12-01 10:30:48 27 4
gpt4 key购买 nike

我有几个线程执行一些工作,然后必须进入休眠/等待不确定的时间。稍后他们都需要被叫醒并继续工作。我可以通过在对象上调用 wait() ,然后在需要恢复时在同一对象上调用 notifyall() 来实现此目的。在研究这个问题时,我发现了这个教程:http://tutorials.jenkov.com/java-concurrency/thread-signaling.html显然,通过将信号存储在信号类中并检查 while 循环内的信号成员变量来防止丢失信号和虚假唤醒是一种很好的做法。以下是教程中的代码示例:

public class MonitorObject{
}

public class MyWaitNotify3{

MonitorObject myMonitorObject = new MonitorObject();
boolean wasSignalled = false;

public void doWait(){
synchronized(myMonitorObject){
while(!wasSignalled){
try{
myMonitorObject.wait();
} catch(InterruptedException e){...}
}
//clear signal and continue running.
wasSignalled = false;
}
}

public void doNotify(){
synchronized(myMonitorObject){
wasSignalled = true;
myMonitorObject.notify();
}
}
}

这段代码可以工作,但我需要唤醒所有线程,而不仅仅是一个线程。如果我用 myMonitorObject.notifyAll(); 替换 myMonitorObject.notify(); ,这将不起作用,因为恢复工作的第一个线程将设置 wasSignalled code> 标志为 false,所有其他线程将被困在 while 循环中。

我做了一些更改,使我能够唤醒所有线程:

MonitorObject myMonitorObject = new MonitorObject();
boolean wasSignalled = false;

public void doWait(){
synchronized(myMonitorObject){
while(!wasSignalled){
try{
myMonitorObject.wait();
} catch(InterruptedException e){

}
}

}
}

public void resetSignal() {
wasSignalled = false;
}

public void doNotifyAll() {
synchronized(myMonitorObject){
wasSignalled = true;
myMonitorObject.notifyAll();
}
}

但这不是一个很好的解决方案,因为现在我无法只唤醒一个线程,并且我必须在 doNotify 之后重置信号,然后才能再次使用 doWait。

有没有人有一个解决方案,使我能够在正在等待的线程上使用 notifynotifyAll

关于该示例的一件事我不明白,为什么我必须使用单独的 MonitorObject 类?为什么我不能只在 MyWaitNotify 类本身上调用 waitnotify

像这样:

public class WaitNotify {
boolean wasSignalled = false;

public void doWait(){
synchronized(this){
while(!wasSignalled){
try{
wait();
} catch(InterruptedException e){

}
}
}
}

public void resetSignal() {
wasSignalled = false;
}

public void doNotifyAll() {
synchronized(this){
wasSignalled = true;
notifyAll();
}
}
}

这似乎有效,有什么理由我不应该这样做?

最佳答案

使用生成整数。当一个线程阻塞时,阻塞直到生成整数改变。在调用 notifyAll 之前,增加生成整数。

关于Java,等待并notifyAll : guard against spurious wakeups,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35108642/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com