从并发程序中的BlockingQueue获取对象的最佳方法?

时间:2020-03-05 18:42:21  来源:igfitidea点击:

在并发程序中不违反竞争条件的情况下,将对象从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();
   }
 }

该示例取自BlockingQueue的JDK 1.6文档。因此,我们可以看到我们正在以正确的方式进行操作。这是告诉我们必须工作的报价:

Memory consistency effects: As with
  other concurrent collections, actions
  in a thread prior to placing an object
  into a BlockingQueue happen-before
  actions subsequent to the access or
  removal of that element from the
  BlockingQueue in another thread.