서버가 클라이언트에서 메시지를 수신 할 때마다 메시지가 대기열에 저장됩니다. 여러 스레드가 대기열에 데이터를 입력 할 수 있지만 한 번에 하나의 스레드 만 읽거나 처리해야합니다. 대기열에 메시지가있는 한 처리 스레드가 살아 있어야합니다. 이 작업을 어떻게 수행합니까?메시지 대기열이 비어 있지 않으면 처리 스레드를 항상 실행하십시오.
처리 로직을 동기화 된 메서드에 넣고 모든 요청에 대해이 메서드를 호출하는 새 스레드를 시작하면 메모리에있는 모든 스레드가있는 리소스가 낭비되지 않고 차례를 기다리고 있지 않습니까? 나는 각 요청을 시작하려고로, 하나의 처리 스레드를 사용하는 경우 다른 한편으로
, 이미 실행되어 있지 않은 경우 :public void onMessage(String message) {
addToQueue(message);
synchronized (lock) {
if (!processingThread.isAlive())
processingThread.start();
}
}
// processing thread
public void process() {
while (true) {
String message = queue.poll();
synchronized (lock) {
if (message == null)
return;
}
// process message
}
}
어떻게 내가이 시나리오에 실행되지 않도록 할 수 있습니다 :
- 처리 스레드는 다음 요소에 대한 대기열을 폴링합니다. 공유 잠금을 가져 와서 동기화 된 블록으로 들어갑니다. 큐에서 읽은 요소가
null
인지 확인하여 큐가 비어 있음을 확인합니다. 스레드가 잠금을 해제하지만 해당isAlive
플래그가 아직 false로 설정되지 않았습니다. - 클라이언트 요청이 도착하여 대기열에 메시지를 추가합니다. 수신 메소드는 잠금을 가져 와서 동기화 된 블록으로 들어갑니다. 처리 스레드가 아직 살아 있기 때문에 시작할 필요가 없습니다. 이 메소드는 잠금을 해제합니다.
- 처리 스레드가 이제 잠금을 해제하고 종료됩니다.
이 경우 큐에 처리되지 않은 메시지가 하나 있습니다. 이 시나리오가 발생할 수 있습니까? 대담한 문장에서 알 수 있듯이 스레드가 죽기 전에 잠금 장치가 해제 될 수 있습니까?
하지만 put 메서드는 동기화되어 있으므로 여러 생성자를 사용하려면 차례를 기다려야 할 것이므로 동시 큐의 장점을 잃을 것입니다. 다른 방법이 있습니까? – devil0150
put은 두 생산자가 동시에 대기열에 추가하는 것을 방지하기 위해 동기화되어야하지만 생산자는 대기열이 가득 차면 대기해야합니다. 대기열이 가득 차 있지 않으면 생성자는 해당 메시지를 추가하고 notifyAll을 호출하고 대기하지 않고 종료합니다. –
하지만 두 명의 제작자가 동시에 대기열에 추가 할 수있게하고 싶습니다. 그리고이 경우 두 명의 다른 제작자가 동시에 'put'을 호출하려고하면 그 중 하나는 대기열이 가득차 있지 않아도 다른 하나가 반환하도록 기다려야합니다. – devil0150