TransferQueue instance

  java

Order

This article mainly introduces the TransferQueue.

TransferQueue

TransferQueue(Java7 introduction) inherited the BlockingQueue(BlockingQueue also inherited the Queue) and extended some new methods. Producers will block until the elements added to the queue are consumed by a consumer (not just added to the queue).

LinkedTransferQueue

LinkedTransferQueue is actually a superset of ConcurrentLinkedQueue, SynchronousQueue (Fair Mode) and LinkedBlockingQueue. And LinkedTransferQueue is better because it not only integrates the functions of these classes, but also provides a more efficient implementation.

Contrast SynchronousQueue

SynchronousQueue uses two queues (one for waiting producers and the other for waiting consumers) and a lock to protect the two queues. LinkedTransferQueue uses CAS operations to implement a non-blocking method, which is the key to avoid serialization processing tasks.

the usage scenarios

TransferQueue can be very useful when we don’t want producers to overproduce messages to avoid OutOfMemory errors. In such a design, the consumer’s spending power will determine the speed at which producers produce messages.

Example

public class LinkedTransferQueueDemo {
    static LinkedTransferQueue<String> lnkTransQueue = new LinkedTransferQueue<String>();
    public static void main(String[] args) {
        ExecutorService exService = Executors.newFixedThreadPool(2);
        Producer producer = new LinkedTransferQueueDemo().new Producer();
        Consumer consumer = new LinkedTransferQueueDemo().new Consumer();
        exService.execute(producer);
        exService.execute(consumer);
        exService.shutdown();
    }
    class Producer implements Runnable{
        @Override
        public void run() {
            for(int i=0;i<3;i++){
                try {
                    System.out.println("Producer is waiting to transfer...");
                    lnkTransQueue.transfer("A"+i);
                    System.out.println("producer transfered element: A"+i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class Consumer implements Runnable{
        @Override
        public void run() {
            for(int i=0;i<3;i++){
                try {
                    System.out.println("Consumer is waiting to take element...");
                    String s= lnkTransQueue.take();
                    System.out.println("Consumer received Element: "+s);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Output

Producer is waiting to transfer...
Consumer is waiting to take element...
producer transfered element: A0
Producer is waiting to transfer...
Consumer received Element: A0
Consumer is waiting to take element...
producer transfered element: A1
Producer is waiting to transfer...
Consumer received Element: A1
Consumer is waiting to take element...
Consumer received Element: A2
producer transfered element: A2

doc