2012-03-06 4 views
12

전송할 메시지가 포함 된 BlockingQueues가 여러 개 있습니다. 대기열보다 적은 수의 소비자가있을 수 있습니까? 대기열을 반복하고 (대기중인) 폴링을 유지하고 모든 대기열에 대해 스레드를 원하지 않습니다. 대신, 어떤 대기열에서 메시지를 사용할 수있을 때 깨어 난 스레드를 하나 갖고 싶습니다.다중 차단 대기열, 단일 사용자

+5

여러 생성자에게 제공되는 단일 차단 대기열과의 차이점은 무엇입니까? –

+0

Alex가 달성하기를 원하는 것은 다중 차단 큐의 맨 위에 차단 대기열 (래퍼)을 만들어 소비자가 단일 차단 대기열에서 대기 할 수 있도록하는 것입니다. 아마도 Alex가 제작자에게 동일한 차단 대기열 인스턴스를 사용하도록 요구하는 것을 막을 수 있습니다. – sjlee

+1

문제는 내가 큐당 여러 소비자를 원하지 않는다는 것입니다. 모든 큐를 하나의 큐에 덤프하면 소비자는 같은 큐에서 먹을 수 있습니다. 그래서 A가있는 대기열이 있고 B가있는 대기열이 있습니다. 다른 B가 아직 취해지고있는 한 B는 취해질 수 없습니다. – Alex

답변

6

당신이 할 수있는 한 가지 트릭은 대기열을 대기열로 만드는 것입니다. 따라서 모든 스레드가 구독하는 단일 차단 대기열을 사용하면됩니다. 그런 다음 BlockingQueues 중 하나에 항목을 대기열에 추가하면 차단 대기열도이 단일 대기열에 대기열에 포함됩니다. 그래서 당신은 같은 것이다 :

BlockingQueue<WorkItem> producers[] = new BlockingQueue<WorkItem>[NUM_PRODUCERS]; 
BlockingQueue<BlockingQueue<WorkItem>> producerProducer = new BlockingQueue<BlockingQueue<WorkItem>>(); 

을 다음 새 작업 항목을받을 때

void addWorkItem(int queueIndex, WorkItem workItem) { 
    assert queueIndex >= 0 && queueIndex < NUM_PRODUCERS : "Pick a valid number"; 
    //Note: You may want to make the two operations a single atomic operation 
    producers[queueIndex].add(workItem); 
    producerProducer.add(producers[queueIndex]); 
} 

이제 소비자 수있는 producerProducer의 모든 블록. 이 전략이 얼마나 가치가 있을지 모르지만 원하는대로 성취합니다.

+0

간단하고 효과적입니다! 감사! – Alex

+0

@Alex : 문제 없습니다 - 어떻게 작동하는지 궁금합니다. – mindvirus

4

LinkedBlockingMultiQueue은 사용자가 원하는 것을 수행합니다. 소비자가 임의의 BlockingQueues를 차단할 수는 없지만 단일 "다중 대기열"에서 "하위 대기열"을 만들고 동일한 효과를 얻을 수 있습니다. 생산자가 하위 대기열에서 제공하고 소비자는 단일 다중 대기열을 폴링하여 모든 요소를 ​​기다리는 것을 차단할 수 있습니다.

또한 다른 요소를 고려하기 전에 일부 큐에서 요소를 가져 오는 우선 순위를 지원합니다.

예 :

LinkedBlockingMultiQueue<Int, String> q = new LinkedBlockingMultiQueue<>(); 
q.addSubQueue(1 /* key */, 10 /* priority */); 
q.addSubQueue(2 /* key */, 10 /* priority */); 
LinkedBlockingMultiQueue<Int, String>.SubQueue sq1 = q.getSubQueue(1); 
LinkedBlockingMultiQueue<Int, String>.SubQueue sq2 = q.getSubQueue(2); 

그런 다음 당신이 제공 할 수 있습니다 및 설문 조사 :

sq1.offer("x1"); 
q.poll(); // "x1" 
sq2.offer("x2"); 
q.poll(); // "x2" 

면책 조항 : 나는 도서관의 저자입니다.