BlockingQueue和TransferQueue之间的区别

我有点混淆了BlockingQueue / LinkedBlockingQueue和jsr166y和java 7中新的TransferQueue / LinkedTransferQueuetypes之间的区别

来自TransferQueue JavaDocs :

制造者可以等待消费者接收元素的阻塞队列。 一个TransferQueue可能对消息传递应用程序很有用,在这些应用程序中,生产者有时候(使用方法传输(E))等待消费者调用take或poll来接收元素,而在另外一些时候则通过方法put来排队(而不是等待接收)。

换句话说,当你使用BlockingQueue的时候,你只能把元素放入队列(如果队列已满则阻塞)。 有了TransferQueue,你也可以阻塞,直到其他线程收到你的元素(你必须使用新的transfer方法)。 这是不同的。 使用BlockingQueue,您不能等到其他线程删除您的元素(只有当您使用SynchronousQueue,但这不是一个真正的队列)。

除此之外,TransferQueue也是一个BlockingQueue。 在TransferQueue中查看新的可用方法: http : //download.oracle.com/javase/7/docs/api/java/util/concurrent/TransferQueue.html (transfer,tryTransfer,hasWaitingConsumer,getWaitingConsumerCount)。


Java SE 7中的Collections Framework增强function明确地说:

TransferQueue接口已被添加。 这是BlockingQueue接口的一个改进,生产者可以等待消费者接收元素。 新版本的一个实现也包含在本版本LinkedTransferQueue中。

虽然似乎有某种forms的performance差异, 请参阅ArrayBlockingQueue与LinkedTransferQueue和朋友

简而言之,BlockingQueue保证生产者创build的元素必须在队列中,而TransferQueue进一步,保证该元素被某些消费者“消费”。

很久以前的问题和@彼得的答案是非常详细的。 对于想要了解TransferQueue如何在实践中使用的人,也许可以参考下面的实况演示。

 import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.TransferQueue; public class TransferQueueExample { TransferQueue<String> queue = new LinkedTransferQueue<String>(); class Producer implements Runnable{ @Override public void run() { // TODO Auto-generated method stub for(int i = 0; i < 2; i++){ try{ System.out.println("Producer waiting to transfer: " + i); queue.transfer("" + i); System.out.println("Producer transfered: " + i); }catch(Exception e){ e.printStackTrace(); } } } } class Consumer implements Runnable{ @Override public void run() { // TODO Auto-generated method stub for(int i = 0; i < 2; i++){ try{ Thread.sleep(2000); System.out.println("Consumer waiting to comsume: " + i); queue.take(); System.out.println("Consumer consumed: " + i); }catch(Exception e){ e.printStackTrace(); } } } } public static void main(String args[]){ TransferQueueExample example = new TransferQueueExample(); new Thread(example.new Producer()).start(); new Thread(example.new Consumer()).start(); } } 

输出是:

 Producer waiting to transfer: 0 Consumer waiting to comsume: 0 Consumer consumed: 0 Producer transfered: 0 Producer waiting to transfer: 1 Consumer waiting to comsume: 1 Consumer consumed: 1 Producer transfered: 1 

transfer是差异发生的地方。

将元素转移给消费者,如果需要的话等待。

更确切地说,如果消费者已经等待接收它(在接受或定时轮询中),则立即传送指定的元素,否则等待直到消费者接收到该元素。

作为javadoc, transfer将等到消费者拿走产品。

这就是为什么"Producer waiting to transfer: 0"首先被调用,大约2秒后,消费者收到后, Producer transfered: 0被调用。