동시 프로그램의 BlockingQueue에서 객체를 가져오는 가장 좋은 방법은 무엇입니까?
-
09-06-2019 - |
문제
경쟁 조건에 부딪히지 않고 동시 프로그램에서 BlockingQueue에서 객체를 가져오는 가장 좋은 방법은 무엇입니까?나는 현재 다음을 수행하고 있으며 이것이 최선의 방법이라고 확신하지 않습니다.
BlockingQueue<Violation> vQueue;
/*
in the constructor I pass in a BlockingQueue object
full of violations that need to be processed - cut out for brevity
*/
Violation v;
while ( ( v = vQueue.poll(500, TimeUnit.MILLISECONDS) ) != null ) {
// do stuff with the violation
}
아직 경쟁 조건에 도달하지 못했습니다.하지만 이것이 정말 안전한지 확신할 수는 없습니다.
해결책
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
이 예는 JDK 1.6 문서 BlockingQueue
.따라서 올바른 방식으로 수행하고 있음을 알 수 있습니다.다음은 작동해야 함을 알려주는 인용문입니다.
메모리 일관성 효과:다른 동시 컬렉션과 마찬가지로, 다른 스레드에서 블록 링크에서 해당 요소의 액세스 또는 제거 후에 동작이 발생하기 전에 Blockingqueue에 객체를 배치하기 전에 스레드의 동작.
제휴하지 않습니다 StackOverflow