Java:等待线程异常通知

时间:2016-04-15 13:32:10

标签: java multithreading

我正在使用"收发器"从客户端向服务器发送请求并等待响应。我从[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;
    }
}

我发现有时发送和等待线程并不总是被响应通知,也没有被打断(根据我的理解)但是被等待的某些神秘的东西唤醒了#34;。这是日志:

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

您可能会看到第2/3/4行是一个事务,而第5/6/7行是另一个事务,但第8/9行显示了该问题。如果收发器被某人唤醒,它应该打印线程的名称,或者如果它被中断,它应该通过LogManager.ex(ex)打印异常堆栈。但它没有。我做错了什么?

1 个答案:

答案 0 :(得分:0)

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

当你致电wait()时,它可能会发出虚假的声音。

简而言之;

  • 仅在州改变后通知。
  • 只等待一段时间,在等待之前检查状态检查。