Java:异常通知正在等待的线程
我使用一个“收发机”从客户端向服务器发送请求并等待响应。我从[here][1]学习了两个线程之间的通信方式,并编写了以下代码: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();
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循环中等待,在等待之前检查状态检查