我正在使用"收发器"从客户端向服务器发送请求并等待响应。我从[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)打印异常堆栈。但它没有。我做错了什么?
答案 0 :(得分:0)
当您致电notify()
时,只会通知正在等待的线程。如果线程正在执行其他操作,则通知将丢失。
当你致电wait()
时,它可能会发出虚假的声音。
简而言之;