並行プログラムで 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
. 。したがって、正しい方法で実行していることがわかります。これが機能する必要があることを示す引用は次のとおりです。
メモリの一貫性による影響:他の同時コレクションと同様に、オブジェクトをブロッキングに配置する前のスレッド内のアクションは、別のスレッドのブロッキングキューからその要素のアクセスまたは削除に続くアクションの前に行われます。
所属していません StackOverflow