简体   繁体   English

BlockingQueue和TransferQueue之间的区别

[英]Difference between BlockingQueue and TransferQueue

关于BlockingQueue / LinkedBlockingQueue与jsr166y和java 7中新的TransferQueue / LinkedTransferQueue类型之间的区别,我有点困惑

From TransferQueue JavaDocs : 来自TransferQueue JavaDocs

A BlockingQueue in which producers may wait for consumers to receive elements. 一个BlockingQueue,生产者可以等待消费者接收元素。 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. TransferQueue可能在例如消息传递应用程序中很有用,其中生产者有时(使用方法转移(E))等待消费者调用take或poll接收元素,而在其他时候将元素排队(通过方法put)而不等待接收。

In other words, when you use BlockingQueue, you can only put element into queue (and block if queue is full). 换句话说,当您使用BlockingQueue时,您只能将元素放入队列(如果队列已满,则阻止)。 With TransferQueue, you can also block until other thread receives your element (you must use new transfer method for that). 使用TransferQueue,您也可以阻止,直到其他线程接收到您的元素(您必须使用新的transfer方法)。 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,您不能等到其他线程删除您的元素(仅当您使用SynchronousQueue时,但这不是真正的队列)。

Other than this, TransferQueue is also a BlockingQueue. 除此之外,TransferQueue也是一个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中查看新的可用方法: http//download.oracle.com/javase/7/docs/api/java/util/concurrent/TransferQueue.html (transfer,tryTransfer,hasWaitingConsumer,getWaitingConsumerCount)。


Collections Framework Enhancements in Java SE 7 says explicitly: Java SE 7中的集合框架增强功能明确说明:

The interface TransferQueue has been added. 添加了接口TransferQueue。 It is a refinement of the BlockingQueue interface in which producers can wait for consumers to receive elements. 它是BlockingQueue接口的改进,生产者可以在其中等待消费者接收元素。 One implementation of the new interface is also included in this release, LinkedTransferQueue. 此版本中还包含新接口的一个实现LinkedTransferQueue。

简而言之,BlockingQueue保证生产者生成的元素必须在队列中,而TransferQueue更进一步,它保证元素被一些消费者“消耗”。

A question long time ago and @Peter's answer is really elaborate. 很久以前的一个问题和@Peter的回答非常精细。 For people who wants to know how TransferQueue works in practice, maybe you can refer to the live demo below. 对于想要了解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: 0Producer transfered: 0然后调用Producer transfered: 0

Although there does seem to be some form of performance difference; 虽然似乎确实存在某种形式的性能差异; see ArrayBlockingQueue vs LinkedTransferQueue and friends 请参阅ArrayBlockingQueue与LinkedTransferQueue和朋友

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM