gpt4 book ai didi

Java 等待/通知 - 不唤醒线程

转载 作者:行者123 更新时间:2023-12-03 12:58:37 25 4
gpt4 key购买 nike

我正在尝试做一个小练习来习惯等待/通知。
我想要做的只是启动一个线程,然后让它进入等待状态并多次使用通知唤醒它。

我的代码是:

public class Simple{
static final Thread mainThread = Thread.currentThread();

public static void main(String[] args) throws InterruptedException {
PrintThread printer = new PrintThread(0);
printer.start();

synchronized (mainThread){
System.out.println("main sleeping while waiting for printer to be started");
mainThread.wait();
System.out.println("main woke up");


for (int i = 0; i < 1000; i++) {
synchronized (printer){
System.out.println("added num "+i);
printer.numToPrint = i;
System.out.println("main waking up printer");
printer.notifyAll();
System.out.println("main sleeping");
mainThread.wait();
System.out.println("main woke up");
}
}

}

}
}

class PrintThread extends Thread{
public int numToPrint = -1;

public PrintThread(int numToPrint){
this.numToPrint = numToPrint;
}

@Override
public synchronized void run() {
System.out.println("printer started");
while (true){
try {
synchronized (Simple.mainThread){
System.out.println("printer waking up main");
Simple.mainThread.notifyAll();
}
System.out.println("printer sleeping");
wait();
System.out.println("printer woke up");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("printing num "+numToPrint);
}
}

}

我希望这会像
main sleeping while waiting for printer to be started
printer started
printer waking up main
printer sleeping
main woke up
added num 0
main waking up printer
main sleeping
printer woke up
printing num 0
printer waking up main
printer sleeping
main woke up
added num 1
...

相反,这样做:
main sleeping while waiting for printer to be started
printer started
printer waking up main
printer sleeping
main woke up
added num 0
main waking up printer
main sleeping

所以......似乎通知没有唤醒打印机线程?

这不应该是一个死锁,因为通过等待我释放了我拥有的所有锁,所以 主要 不应该有任何锁定 打印机 打印机 应该可以唤醒和打印。

我究竟做错了什么?

最佳答案

很可能在 Print 再次调用 wait() 之前调用了您的 notifyAll() 调用。问题是您对 wait 和 notifyAll 调用的依赖完全按照您希望的顺序发生。这是两个不同的执行线程,所以当然这不能保证,因此你得到了你所拥有的。

实现这一点的更好方法是创建一个公共(public)的第三个共享对象,两个线程都可以获取锁定。这将在两个线程等待访问该对象时同步它们。

此外,您应该阅读 Thread.wait、notify 和 notifyAll 的 Javadocs。如果/当你这样做时,你会看到你不应该在线程上调用这些方法,因为它们用于执行 thread.join (不仅如此,但我的“声名鹊起”是我相信这是我多年前的错误请求当它不在导致它被添加到 Javadoc 的 JavaDoc 中时记录这一点。可能是其他人,但它发生在我要求它之后:))

关于Java 等待/通知 - 不唤醒线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61802200/

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