我正在使用「收發器」將請求從客戶端發送到服務器並等待響應。我是從[這裏]學會[1]的方式來兩個線程之間的溝通,並寫了波紋管代碼:Java:等待線程異常通知
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>@[email protected]@GUIManager.java
1460717229475:DEBUG:2 transceive()@[email protected]
1460717229735:DEBUG:3 forward()@[email protected]
1460717229739:DEBUG:4 transceive(ivoked by: [email protected]@[email protected])@[email protected]
1460717229750:DEBUG:5 transceive()@[email protected]
1460717229768:DEBUG:6 forward()@[email protected]
1460717229768:DEBUG:7 transceive(ivoked by: [email protected]@[email protected])@[email protected]
1460717229770:DEBUG:8 transceive()@[email protected]
1460717234771:DEBUG:9 transceive(ivoked by: NONE)@[email protected]
您可能會看到LINE2/3/4是一個事務,LINE5/6/7是另一個交易,但line8/9示出了該問題。如果收發器被某人喚醒,它應該打印該線程的名稱,或者如果它被中斷,它應該通過LogManager.ex(ex)打印異常堆棧。但事實並非如此。我做錯了什麼?
服務器也在我的電腦上,所以你可以看到響應時間很短。但是日誌行8/9顯示收發器()立即被喚醒,這是不正常的事情。 – howToDeleteMyAccount
關於這個話題在這裏有一個冗長的討論:http://stackoverflow.com/questions/1050592/do-spurious-wakeups-actually-happen – NAMS