Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:异常通知正在等待的线程_Java_Multithreading - Fatal编程技术网

Java:异常通知正在等待的线程

Java:异常通知正在等待的线程,java,multithreading,Java,Multithreading,我使用一个“收发机”从客户端向服务器发送请求并等待响应。我从[here][1]学习了两个线程之间的通信方式,并编写了以下代码: public class ThreadEvent { private Object lock; private Object data; private String ntfInfo; public ThreadEvent() { data = null; lock = new Object();

我使用一个“收发机”从客户端向服务器发送请求并等待响应。我从[here][1]学习了两个线程之间的通信方式,并编写了以下代码:

public class ThreadEvent {

    private Object lock;
    private Object data;
    private String ntfInfo;

    public ThreadEvent() {
        data = null;
        lock = new Object();
        ntfInfo = "NONE";
    }

    public boolean await(int time) {
        synchronized (lock) {
            try {
                lock.wait(time);
                return true;
            } catch (InterruptedException ex) {
                LogManager.ex(ex);
                return false;
            }
        }
    }

    public void signal() {
        synchronized (lock) {
            ntfInfo = (new Throwable()).getStackTrace()[1].getMethodName() + "@"
                    + (new Throwable()).getStackTrace()[1].getClassName() + "@"
                    + "line" + (new Throwable()).getStackTrace()[1].getLineNumber() + "@"
                    + (new Throwable()).getStackTrace()[1].getFileName();
            lock.notify();
        }
    }

    public synchronized void putData(Object data) {
        this.data = data;
    }

    public synchronized Object takeData() {
            Object res = data;
            data = null;
            return res;
    }

    public String takeNtfInfo() {
        String info = ntfInfo;
        ntfInfo = "NONE";
        return info;
    }
}
我发现有时发送和等待线程并不总是被响应通知,也不总是被中断(根据我的理解),而是被某种神秘的“东西”从等待中唤醒。以下是日志:

1460717223039:DEBUG:1   starting... @<init>@wsclientapp.GUIManager@line57@GUIManager.java
1460717229475:DEBUG:2   transceive()@line30@WSTransceiver.java
1460717229735:DEBUG:3   forward()@line69@WSTransceiver.java
1460717229739:DEBUG:4   transceive(ivoked by: forward@wsclientapp.util.WSTransceiver@line73@WSTransceiver.java)@line42@WSTransceiver.java
1460717229750:DEBUG:5   transceive()@line30@WSTransceiver.java
1460717229768:DEBUG:6   forward()@line69@WSTransceiver.java
1460717229768:DEBUG:7   transceive(ivoked by: forward@wsclientapp.util.WSTransceiver@line73@WSTransceiver.java)@line42@WSTransceiver.java
1460717229770:DEBUG:8   transceive()@line30@WSTransceiver.java
1460717234771:DEBUG:9   transceive(ivoked by: NONE)@line42@WSTransceiver.java
1460717223039:调试:1正在启动@@wsclientapp。GUIManager@line57@GUIManager.java
1460717229475:调试:2个收发器()@line30@WSTransceiver.java
1460717229735:调试:3前进()@line69@WSTransceiver.java
1460717229739:调试:4个收发器(输入者:forward@wsclientapp.util.WSTransceiver@line73@WSTransceiver.java)@line42@WSTransceiver.java
146071729750:调试:5个收发器()@line30@WSTransceiver.java
1460717229768:调试:6向前()@line69@WSTransceiver.java
1460717229768:调试:7收发机(输入者:forward@wsclientapp.util.WSTransceiver@line73@WSTransceiver.java)@line42@WSTransceiver.java
1460717229770:调试:8收发器()@line30@WSTransceiver.java
1460717234771:调试:9收发器(ivoked by:无)@line42@WSTransceiver.java
您可能会看到第2/3/4行是一个事务,第5/6/7行是另一个事务,但第8/9行显示了问题。如果收发器被某人唤醒,它应该打印线程的名称,或者如果它被中断,它应该通过LogManager.ex(ex)打印异常堆栈。但事实并非如此。我做错了什么?

当您调用
notify()
时,只会通知正在等待的线程。如果线程正在执行其他操作,则通知将丢失

当您调用
wait()
时,它可能会错误地唤醒

简言之

  • 仅在状态更改后通知
  • 只在while循环中等待,在等待之前检查状态检查

服务器也在我的电脑上,因此您可以看到响应时间非常短。但是日志第8/9行显示收发器()立即被唤醒,这是一件异常的事情。这里有一个关于这个主题的冗长讨论:我的问题是等待的线程WSTransceiver。有时候,收发器(数据包包)不是被WSTransceiver.forward(数据包包)的通知唤醒的,而是被“其他东西”唤醒的。您可以看到,我在ThreadEvent.signal()中跟踪了通知者/调用者的信息,但什么也没有捕获。我终于意识到1460717234771(日志行9)和1460717229770(日志行8)之间的差异实际上是5秒,因此这是由于同一链接中正在进行的文件传输而导致的网络超时。这就解决了,这里没有什么神秘的。