views:

941

answers:

1

What is the best method to get objects out of a BlockingQueue, in a concurrent program, without hitting a race condition? I'm currently doing the following and I'm not convinced it is the best method:

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
}

I have yet to hit a race condition... but, I'm none too sure if this is truly safe.

Matt

+2  A: 
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();
   }
 }

This example was taken from the JDK 1.6 docs of BlockingQueue. So You can see that you are doing it the right way. Here's the quote which tells you that it have to work:

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.

david