이 방법은 메시지 처리를 시작하는 이벤트 루프를 알리지 않습니다. 그러나 이벤트 루프가 이미 메시지를 처리 중이면이 메서드는 이벤트 루프가 끝날 때 트리거되는 완료된 이벤트 처리 알림을받을 때까지 차단합니다.서버 모드의 스레드 차단
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();
}
}
이것은 클라이언트 모드에서 작동합니다. 서버 모드로 전환하고 이벤트 루프 처리에 소요 된 시간이 너무 빠르면 위의 방법으로 이벤트가 완료 될 때까지 기다릴 수 없습니다. 어떤 이유로 이벤트 complete 통지는 processingEvent 검사 이후와 eventCompleted.wait() 전에 전송됩니다. 출력 문을 제거해도 아무런 차이가 없습니다. 나는 클라이언트 모드에서 같은 문제를 반복 할 수 없다.
왜 이것은 서버 모드에서만 발생하며 이런 일이 발생하지 않도록하려면 어떻게해야합니까? - BTW 약 300 이벤트 후 randomely 클라이언트 모드에서 일어난
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;
}
여기 교착 상태 문제없이 작동하는 것 같다 개정 코드 :
다음은 eventReady 기다려 eventCompleted 알림입니다. processingEvent
만약
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
나는 LinkedBlockingQueue가 0이 아닌 1로 제한된다는 것을 믿는다. API 문서에 따르면 0 제한은 생성자에서 IllegalArgumentException을 던질 것이다. –
1 번으로 대기열 1 이벤트가됩니다. 1 작업 및 1 대기 중. 0은 이벤트 처리 프로그램에 의해 대기열에서 제거 될 때까지 제공자가 차단됨을 의미합니다. 대기중인 이벤트가 없습니다. 0이 전형적인 패턴입니다. – Gray