Вопрос

Я немного смущен в том, в чем разница между Blockqueue/LinkedBlockingqueue и новыми типами Transforequeue/LinkedTransferqueue от JSR166Y и Java 7

Это было полезно?

Решение

Из Transferqueue Javadocs:

Блокингкейуэ, в которой производители могут ждать, пока потребители получат элементы. Transferqueue может быть полезна, например, в приложениях передачи сообщений, в которых производители иногда (используя метод передачи (e)) ожидает получения элементов, потребители, вызывая привлечение или опрос, в то время как в других случаях элементы Enqueue (через метод PUT) без ожидания получения.

Другими словами, когда вы используете BlockingQueue, вы можете положить элемент только в очередь (и блокировать, если очередь заполнена). С Transferqueue вы также можете блокировать, пока другой поток не получит ваш элемент (вы должны использовать новый transfer Метод для этого). Это разница. С BlockingQueue вы не можете ждать, пока другой нить не удалит ваш элемент (только тогда, когда вы используете Synchronousqueue, но это на самом деле не в очереди).

Кроме этого, Transferqueue также является блокировкой. Проверьте новые доступные методы в Transferqueue: http://download.oracle.com/javase/7/docs/api/java/util/concurrent/transferqueue.html (Transfer, Trytransfer, HaswaitingConsumer, GetWaitingConsumercount).


Усовершенствования структуры коллекций в Java SE 7 говорит явно:

Интерфейс Transferqueue был добавлен. Это уточнение интерфейса блокировки, в котором производители могут ждать, пока потребители получат элементы. Одна реализация нового интерфейса также включена в этот релиз, LinkedTransferqueue.

Другие советы

Вопрос давным -давно и ответ @Питера действительно сложный. Для людей, которые хотят знать, как работает 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();
    }

}

Вывод:

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

А transfer где происходит разница.

Передает элемент потребителю, ожидая, если это необходимо, чтобы сделать это.

Точнее, передает указанный элемент немедленно, если есть потребитель, который уже ожидает его получения (в опросе или временном опросе), иначе ожидает, пока элемент не будет получен потребителем.

Как Javadoc, transfer Будет подождать, пока потребитель не заберут продукт.

Вот почему "Producer waiting to transfer: 0" называется первым и примерно через 2 секунды, после того как он был получен потребителем, Producer transfered: 0 тогда называется.

Короче говоря, BlockingQueue гарантирует, что элемент, изготовленный производителем, должен находиться в очереди, в то время как Transferqueue становится еще дальше, он гарантирует, что элемент «потребляется» некоторым потребителем.

Хотя, кажется, есть какая -то форма разницы в производительности; видеть Arrayblockingqueue против LinkedTransferqueue и друзей

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top