Java wait()不会被notify() [英] Java wait() does not get waked by notify()

查看:218
本文介绍了Java wait()不会被notify()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我使用SerialPortEventListener在一个主要的线程,在工作线程我有一个客户端套接字通信到服务器。
因为在这个工作线程到达 return 之后,我仍然需要在主线程中完成一些换行工作,我想创建一个pseudothread主线程,直到它从侦听器onEvent方法通知。



但是这个pseudothread似乎永远在等待。



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



PseudoThread waiting已显示,但PseudoThread清醒未显示。


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


PS如果我在Main类中使用 public final Object lock = new Object(); 创建一个锁,并替换 main .pseudoThread main.lock ,我得到java.lang.IllegalMonitorStateException。

 私有类伪实现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();
//更多代码。包括启动工作线程
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);
}

和在监听器类(也在主线程中运行) >

  //类构造函数; 
public Arduino(Main Main){
this.main = Main;
}
//监听方法
public void serialEvent(SerialPortEvent oEvent){
//一些代码与工作线程交互。
record();

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


解决方案

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



无论如何,请重构你的代码不要使用同步的Thread实例的不良做法。去ReentrantLock或CoundDownLatch的东西。


Hallo I've been debugging my code for a whole day already, but I just can't see where could be wrong.

I use SerialPortEventListener on a main thread, in a working thread I have a client socket communicating to a server. Since after this working thread reach return, I still need some wrap up work done in the main thread, i want to create a "pseudothread" that wait in the main thread until the it is notified from the listener onEvent method.

but this pseudothread seems to be waiting forever.

I checked the locked thread pseudoThread, they should have the same object id in the Runnable and in Listener class.

"PseudoThread waiting" got displayed, but PseudoThread awake is never showed.

Console output shows: PseudoThread waiting .. .. false notified pseudothread.

PS if I create a lock in Main class with public final Object lock = new Object(); and replace all main.pseudoThread with main.lock, I get 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;
            }
        }

    }

}

in main method:

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);
}

and in the listener class (which also runs in main thread)

//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.");
        }
}

解决方案

As suggested by james it could be lost notification case or it could be that.. Two Threads 1- Your Main Thread and 2- Pseudo thread Are waiting on the same Thread Instance Lock (main.pseudoThread)( Main thread waits on the same lock by calling join method). Now you are using notify which wakes the Main thread from join method and not the one waiting in your Pseudo. To check for the second case try calling notifyall in record this will either confirm the second case or will rule this possibility.

Anyways please refactor your code not to use synch on Thread instance its bad practice. Go for ReentrantLock or CoundDownLatch something.

这篇关于Java wait()不会被notify()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆