Java BlockingQueue和TransferQueue之间的区别

Java BlockingQueue和TransferQueue之间的区别,java,concurrency,jsr166,Java,Concurrency,Jsr166,对于BlockingQueue/LinkedBlockingQueue与jsr166y和java 7中新的TransferQueue/LinkedTransferQueue类型之间的区别,我有点困惑: 一种阻塞队列,其中生产者可以等待消费者接收元素。例如,在消息传递应用程序中,TransferQueue可能很有用,在消息传递应用程序中,生产者有时(使用方法transfer(E))等待调用take或poll的消费者接收元素,而有时(通过方法put)让元素排队而不等待接收 换句话说,当您使用Bloc

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

一种阻塞队列,其中生产者可以等待消费者接收元素。例如,在消息传递应用程序中,TransferQueue可能很有用,在消息传递应用程序中,生产者有时(使用方法transfer(E))等待调用take或poll的消费者接收元素,而有时(通过方法put)让元素排队而不等待接收

换句话说,当您使用BlockingQueue时,您只能将元素放入队列(若队列已满,则阻塞)。使用TransferQueue,您还可以阻塞,直到其他线程接收到您的元素(您必须为此使用新的
transfer
方法)。这就是区别。使用BlockingQueue,您不能等待其他线程删除您的元素(仅当您使用SynchronousQueue时,但这实际上不是一个队列)

除此之外,TransferQueue也是一个BlockingQueue。查看TransferQueue中新的可用方法:(transfer、tryTransfer、hasWaitingConsumer、getWaitingConsumerCount)


明确地说:

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


虽然似乎确实存在某种形式的性能差异;请参见

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

很久以前的一个问题和@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();
    }

}
传输
是差异发生的地方

将元素传输给使用者,在必要时等待

更准确地说,如果存在,则立即传输指定的元素 存在一个已在等待接收的使用者(在take或timed中) 轮询),否则将等待元素被使用者接收

与javadoc一样,
传输将等待消费者拿走产品


这就是为什么首先调用
“Producer waiting to transfer:0”
,大约2秒钟后,消费者收到后,调用
Producer transfer:0

我想我浏览文档的速度有点太快了,因为界面太相似了。感谢您的解释。解释得很好,特别是增强部分,它说TransferQueue只不过是BlockingQueue+Receive功能。另一个功能是制作人可以使用
trytTransfer()
仅当有等待的消费者时才提供元素。链接无效
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