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
Difference between BlockingQueue and TransferQueue
21.6k Views Asked by jvdneste AtThere are 4 best solutions below

Although there does seem to be some form of performance difference; see ArrayBlockingQueue vs LinkedTransferQueue and friends

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.

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.
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.
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.
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.
From TransferQueue JavaDocs:
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).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).
Collections Framework Enhancements in Java SE 7 says explicitly: