4

並行プログラムで、競合状態に陥ることなく 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
}

私はまだ競合状態に陥っていません...しかし、これが本当に安全かどうかはわかりません.

4

1 に答える 1

6
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 に配置する前のスレッド内のアクションは、別のスレッドの BlockingQueue からのその要素へのアクセスまたは削除に続くアクションの前に発生します。

于 2008-08-23T05:39:15.197 に答える