此方法通知事件循環開始處理消息。但是,如果事件循環已經在處理消息,則此方法將阻塞,直到它收到完成事件處理的通知(在事件循環結束時觸發)。服務器模式下的線程塊
public void processEvent(EventMessage request) throws Exception {
System.out.println("processEvent");
if (processingEvent) {
synchronized (eventCompleted) {
System.out.println("processEvent: Wait for Event to completed");
eventCompleted.wait();
System.out.println("processEvent: Event completed");
}
}
myRequest = request;
processingEvent = true;
synchronized (eventReady) {
eventReady.notifyAll();
}
}
這適用於客戶端模式。如果我切換到服務器模式,並且在事件循環中處理消息的時間太快,那麼上面的方法會永遠等待事件完成。出於某種原因,事件完成通知在processingEvent檢查之後和eventCompleted.wait()之前發送。如果我刪除輸出語句,這沒有區別。我無法在客戶端模式下重複相同的問題。
爲什麼這隻會發生在服務器模式,我該怎麼做才能防止這種情況發生?
這裏是eventReady等待和eventCompleted通知:
public void run() {
try {
while (true) {
try {
synchronized (eventReady) {
eventReady.wait();
}
nx.processEvent(myRequest, myResultSet);
if (processingEvent > 0) {
notifyInterface.notifyEventComplete(myRequest);
}
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
notifyInterface.notifyException(e, myRequest);
} finally {
processingEvent--;
synchronized (eventCompleted) {
eventCompleted.notifyAll();
}
}
} // End of while loop
} catch (InterruptedException Ignore) {
} finally {
me = null;
}
下面是修改後的代碼,這似乎沒有死鎖問題的工作 - 這BTW發生在randomely客戶端模式後約300事件。
private BlockingQueue<EventMessage> queue = new SynchronousQueue<EventMessage>();
public void processEvent(EventMessage request) throws Exception {
System.out.println("processEvent");
queue.put(request);
}
public void run() {
try {
while (true) {
EventMessage request = null;
try {
request = queue.take();
processingEvent = true;
nx.processEvent(request, myResultSet);
notifyInterface.notifyEventComplete(request);
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
notifyInterface.notifyException(e, request);
} finally {
if (processingEvent) {
synchronized (eventCompleted) {
processingEvent = false;
eventCompleted.notifyAll();
}
}
}
} // End of while loop
} catch (InterruptedException Ignore) {
} finally {
me = null;
}
}
我在看到您的評論之前實施了您的方法。它現在很好用! – mtse 2012-01-03 22:07:55
我相信你的意思是LinkedBlockingQueue的限制是1,而不是0.根據API文檔,0的限制會在構造函數中拋出一個IllegalArgumentException。 – 2012-01-03 22:31:01
第1號將使其排隊1事件。 1個工作和1個排隊。 0意味着提供者將阻塞,直到它由事件處理器出列。沒有事件排隊。 0是典型的模式。 – Gray 2012-01-03 22:32:44