当前位置: 首页 > 面试题库 >

Java wait()不会被notify()唤醒

焦学海
2023-03-14
问题内容

哈罗我已经整天调试了我的代码,但是我看不出哪里出了问题。

我在主线程上使用SerialPortEventListener,在工作线程中,我有一个客户端套接字与服务器通信。由于到达此工作线程之后return,我仍然需要在主线程中完成一些总结工作,因此我想创建一个“伪线程”,在主线程中等待,直到从侦听器onEvent方法通知它为止。

但是这个伪线程似乎一直在等待。

我检查了锁定的线程pseudoThread,它们在Runnable和Listener类中应该具有相同的对象ID。

显示了“ PseudoThread等待中”,但从未显示PseudoThread唤醒。

控制台输出显示:PseudoThread等待.. .. false通知伪线程。

PS如果我创建主类的锁public final Object lock = new Object();,并更换所有main.pseudoThreadmain.lock,我得到java.lang.IllegalMonitorStateException。

private class Pseudo implements Runnable{
    Main main;
    public Pseudo(Main main) {
        this.main = main;
    }

    @Override
    public void run() {
        synchronized(main.pseudoThread){
            try {
                System.out.println("PseudoThread waiting");
                main.pseudoThread.wait();
                System.out.println("PseudoThread awake");
            } catch (InterruptedException e) {
                e.printStackTrace();
                return;
            }
        }

    }

}

在主要方法中:

public static void main(String[] args) {
    Main main = new Main();
    main.initArduino();
    //more code. including starting the working thread
    main.pseudoThread = new Thread(main.new Pseudo(main));
        main.pseudoThread.start();
        try {
            main.pseudoThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
}
private void initArduino() {
    arduino = new Arduino(this);
    if(!arduino.initialize())
        System.exit(1);
}

以及在侦听器类中(它也在主线程中运行)

//class constructor;
public Arduino(Main Main){
    this.main = Main;
}
//listening method
public void serialEvent(SerialPortEvent oEvent){
    //some code to interract with working thread.
    record();

}
private void record(){
        synchronized(main.pseudoThread){
            main.pseudoThread.notify();
            System.out.println("notified pseudothread.");
        }
}

问题答案:

如james所建议,它可能会丢失通知情况,也可能是这样。两个线程1-您的主线程和2-伪线程正在同一线程实例锁(main.pseudoThread)(
主线程在同一锁上等待通过调用join方法
)。现在,您正在使用notify,它会将Main线程从join方法中唤醒,而不是在您的Pseudo中等待的线程。要检查第二种情况,请尝试调用记录中的notifyall,这将确认第二种情况或将排除这种可能性。

无论如何,请重构您的代码,不要在Thread实例上使用synch是一种不好的做法。去ReentrantLock或CoundDownLatch一些东西。



 类似资料:
  • 我继承了,我试图打印我的新估计: foo_my_rf代码 我还尝试: 与相同的结果。预期是类似于sk学默认行为的东西: 这也是我使用时的结果。 我错过了什么?谢谢。 与如何更改Python类的字符串表示有关?

  • 本文向大家介绍Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll),包括了Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll)的使用技巧和注意事项,需要的朋友参考一下 本篇我们来研究一下 wait() notify() notifyAll() 。 DEMO1: wait() 与 notify() DEMO1 输出: 注意: 使用 wait

  • 本文向大家介绍怎么唤醒被阻塞的socket线程?相关面试题,主要包含被问及怎么唤醒被阻塞的socket线程?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 给阻塞时候缺少的资源

  • 正如标题所说,我根本无法让Quartz.net工作。我从NuGet获得了最新版本的Quartz.net(2.2.1)、Common.Logging(2.1.2)、Common.Logging.NLog(2.0.0)和NLog(2.1.0)。触发器没有被触发,而且石英绝对没有记录任何东西。我猜我搞砸了配置。 我的应用程序配置: 有一个作业和一个触发器与之相关: 调度程序将启动,作业和触发器将正确添加

  • 我正在尝试在未来的预定时间生成警报。下面是代码 主要活动。Java语言 警报eceiever.java content\u main。xml 舱单 我试图在一分钟后生成警报,但不幸的是什么都没有发生。我在这里做错了什么?此外,即使在手机重启/关机然后打开后,我如何确保我的日程安排仍然有效?

  • 我是spring webflux和reactor的新手,我希望在发生某些特定异常时有一个回退机制,根据我的研究,onErrorResume方法可以做到这一点,但它不会被调用,我得到500个内部服务器错误,而不是触发回退并阻止此错误。 注意:我使用Spring网络流量,这意味着它在Reactor项目的正常行为中做了一些改变 这是堆栈跟踪