gpt4 book ai didi

java - 在单个线程上发出通知会唤醒所有等待的线程

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:50:51 26 4
gpt4 key购买 nike

有 3 个线程在等待第 4 个,后者发出通知,所有等待的线程都被唤醒。

这是源代码:

class Reader extends Thread {

Calculator calc;

public Reader(Calculator calc) {
this.calc = calc;
}

public void run() {
synchronized(calc) {
try {
System.out.println(Thread.currentThread().getName() + " waiting for calc");
calc.wait();
} catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName() + " Total is: " + calc.total);
}
}

}

class Calculator extends Thread {

public int total = 0;

public void run() {
synchronized(this) {
for (int i = 0; i < 50; i++) {
total += i;
}
notify();
System.out.println("I notified a thread");
}
}

}

public class Notify {

public static void main(String[] args) {
Calculator calc = new Calculator();
Reader r1 = new Reader(calc);
Reader r2 = new Reader(calc);
Reader r3 = new Reader(calc);
r1.start();
r2.start();
r3.start();
calc.start();
}
}

这是我得到的输出:

Thread-2 waiting for calc
Thread-4 waiting for calc
Thread-3 waiting for calc
I notified a thread
Thread-2 Total is: 1225
Thread-3 Total is: 1225
Thread-4 Total is: 1225

不应该只有一个等待线程被唤醒并执行 System.out.println(Thread.currentThread().getName() + "Total is: "+ calc.total); 指令?

最佳答案

您不能以这种方式使用wait/notify。您必须使用 wait 来等待某事,您的代码可以而且必须测试的某事。您应该只在更改另一个线程实际正在等待的内容之后调用 notify,这样它的测试将告诉它不再等待它。

"A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. 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."

换句话说,您的等待逻辑必须如下所示:

  1. 我现在可以做点什么吗?
  2. 如果否,调用等待并转到步骤1。
  3. 做那件事。

您的通知逻辑必须如下所示:

  1. 让另一个线程可以做一些事情。
  2. 调用通知

这些函数不是通用的挂起/恢复机制。它们特别是一种同步由同步块(synchronized block)保护的代码管理的谓词的方法。如果需要,您可以使用自己的可疑/恢复标志或计数来构建暂停/恢复机制。

更新:Måns Rolandi Danielsson 弄清楚了您的具体情况。您的线程正在等待尚未启动/终止的对象。因此,当它向自己发出准备就绪/完成的信号时,其他线程会看到该信号。

关于java - 在单个线程上发出通知会唤醒所有等待的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13257333/

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