gpt4 book ai didi

Java线程自发唤醒

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:13:59 25 4
gpt4 key购买 nike

我有一个 Java 线程做这样的事情:

while (running) {
synchronized (lock) {
if (nextVal == null) {
try {
lock.wait();
} catch (InterruptedException ie) {
continue;
}
}

val = nextVal;
nextVal = null;
}
...do stuff with 'val'...
}

我在其他地方设置的值是这样的:

if (val == null) {
LOG.error("null value");
} else {
synchronized (lock) {
nextVal = newVal;
lock.notify();
}
}

偶尔(字面上每几百万次一次)nextVal 将被设置为 null。我输入了日志消息,我可以看到执行顺序如下所示:

  1. thread1 将 nextVal 设置为 newVal
  2. thread1 调用 lock.notify()
  3. thread2 从 lock.wait() 唤醒
  4. thread2 将 val 设置为 nextVal
  5. thread2 将 nextVal 设置为 null
  6. thread2 用 val 做事
  7. thread2 调用 lock.wait()
  8. thread2 从 lock.wait() 唤醒
    • 没有其他线程调用 lock.notify() 并且线程 2 没有被中断
  9. thread2 将 val 设置为 nextVal(为 null)
  10. 等等

我已经明确检查过锁正在第二次唤醒,它没有被中断。

我是不是做错了什么?

最佳答案

是的,Thread 自发唤醒。这在 the Javadoc 中明确说明:

“线程也可以在没有被通知、中断或超时的情况下唤醒,这就是所谓的虚假唤醒。”

您需要在循环中等待。 javadoc 中也明确提到了这一点:

 synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}

在你的情况下:

while (running) {
synchronized (lock) {
while (nextVal == null) {
try {
lock.wait();
} catch (InterruptedException ie) {
//oh well
}
}

val = nextVal;
nextVal = null;
}
...do stuff with 'val'...
}

关于Java线程自发唤醒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16242888/

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