java BlockingQueue 和 TransferQueue 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7317579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between BlockingQueue and TransferQueue
提问by jvdneste
I am a little bit confused as to what the difference is between BlockingQueue/LinkedBlockingQueue and the new TransferQueue/LinkedTransferQueue types from jsr166y and java 7
我有点困惑 BlockingQueue/LinkedBlockingQueue 和来自 jsr166y 和 java 7 的新 TransferQueue/LinkedTransferQueue 类型之间的区别
回答by Peter ?tibrany
From TransferQueue JavaDocs:
A BlockingQueue in which producers may wait for consumers to receive elements. A TransferQueue may be useful for example in message passing applications in which producers sometimes (using method transfer(E)) await receipt of elements by consumers invoking take or poll, while at other times enqueue elements (via method put) without waiting for receipt.
一个 BlockingQueue,生产者可以在其中等待消费者接收元素。TransferQueue 可能在例如消息传递应用程序中很有用,其中生产者有时(使用方法 transfer(E))等待消费者调用 take 或 poll 接收元素,而在其他时候将元素(通过方法 put)排入队列而不等待接收。
In other words, when you use BlockingQueue, you can only put element into queue (and block if queue is full). With TransferQueue, you can also block until other thread receives your element (you must use new transfer
method for that). This is the difference. With BlockingQueue, you cannot wait until other thread removes your element (only when you use SynchronousQueue, but that isn't really a queue).
换句话说,当您使用 BlockingQueue 时,您只能将元素放入队列(如果队列已满则阻塞)。使用 TransferQueue,您还可以阻塞直到其他线程接收到您的元素(您必须transfer
为此使用新方法)。这就是区别。使用 BlockingQueue,您不能等到其他线程删除您的元素(仅当您使用 SynchronousQueue 时,但这并不是真正的队列)。
Other than this, TransferQueue is also a BlockingQueue. Check out new available methods in TransferQueue: http://download.oracle.com/javase/7/docs/api/java/util/concurrent/TransferQueue.html(transfer, tryTransfer, hasWaitingConsumer, getWaitingConsumerCount).
除此之外,TransferQueue 也是一个 BlockingQueue。查看 TransferQueue 中新的可用方法:http: //download.oracle.com/javase/7/docs/api/java/util/concurrent/TransferQueue.html(transfer、tryTransfer、hasWaitingConsumer、getWaitingConsumerCount)。
Collections Framework Enhancements in Java SE 7says explicitly:
Java SE 7 中的集合框架增强功能明确表示:
The interface TransferQueue has been added. It is a refinement of the BlockingQueue interface in which producers can wait for consumers to receive elements. One implementation of the new interface is also included in this release, LinkedTransferQueue.
接口 TransferQueue 已添加。它是对 BlockingQueue 接口的改进,生产者可以在其中等待消费者接收元素。此版本中还包含新接口的一种实现 LinkedTransferQueue。
回答by swimmingfisher
In short, BlockingQueue guarantees that the element made by producer must be in the queue, while TransferQueue gets one step further, it guarantees that the element "consumed" by some consumer.
简而言之,BlockingQueue 保证生产者制造的元素必须在队列中,而 TransferQueue 更进一步,它保证元素被某些消费者“消费”。
回答by Eugene
A question long time ago and @Peter's answer is really elaborate. For people who wants to know how TransferQueue works in practice, maybe you can refer to the live demo below.
很久以前的一个问题,@Peter 的回答非常详细。想要了解 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();
}
}
The output is:
输出是:
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
The transfer
is where the difference happens.
这transfer
就是差异发生的地方。
Transfers the element to a consumer, waiting if necessary to do so.
More precisely, transfers the specified element immediately if there exists a consumer already waiting to receive it (in take or timed poll), else waits until the element is received by a consumer.
将元素传输给消费者,必要时等待。
更准确地说,如果存在已经等待接收它的消费者(在采取或定时轮询中),则立即传输指定的元素,否则等待直到消费者收到该元素。
As the javadoc, the transfer
will wait until the consumer has taken the product away.
作为 javadoc,他们transfer
会等到消费者拿走产品。
That's the reason why "Producer waiting to transfer: 0"
is called firstly and after about 2 seconds, after it has been received by the consumer, the Producer transfered: 0
is called then.
这就是为什么"Producer waiting to transfer: 0"
首先被调用,大约 2 秒后,在消费者收到后,Producer transfered: 0
然后调用。
回答by Egwor
Although there does seem to be some form of performance difference; see ArrayBlockingQueue vs LinkedTransferQueue and friends
尽管似乎确实存在某种形式的性能差异;参见ArrayBlockingQueue 与 LinkedTransferQueue 和朋友