从并发程序中的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.