Pregunta

Estoy un poco confundido en cuanto a cuál es la diferencia entre Bloquingqueue/LinkedBlokingqueue y los nuevos tipos de transferqueue/LinkedTransferqueue de JSR166Y y Java 7

¿Fue útil?

Solución

De Transferqueue javadocs:

Una Bloquea en la que los productores pueden esperar a que los consumidores reciban elementos. Una transferencia puede ser útil, por ejemplo, en las aplicaciones de aprobación de mensajes en las que los productores a veces (usando la transferencia de método (e)) esperan la recepción de elementos de los consumidores que invocan la toma o la encuesta, mientras que en otros momentos los elementos de enqueue (a través del método se ponen) sin esperar la recepción.

En otras palabras, cuando usa Bloquingqueue, solo puede poner el elemento en la cola (y bloquear si la cola está llena). Con TransferQueue, también puede bloquear hasta que otro hilo reciba su elemento (debe usar nuevo transfer Método para eso). Esta es la diferencia. Con Bloquingqueue, no puede esperar hasta que otro hilo elimine su elemento (solo cuando usa Synchronousqueue, pero eso no es realmente una cola).

Aparte de esto, TransferQueue también es una Bloquea. Consulte los nuevos métodos disponibles en TransferQueue: http://download.oracle.com/javase/7/docs/api/java/util/concurrent/transferqueue.html (Transferir, TryTransfer, HastingingConsumer, GetWaitingConsumercount).


Mejoras del marco de colecciones en Java SE 7 dice explícitamente:

Se ha agregado la interfaz TransferQueue. Es un refinamiento de la interfaz Bloquingqueue en la que los productores pueden esperar a que los consumidores reciban elementos. También se incluye una implementación de la nueva interfaz en esta versión, LinkedTransferqueue.

Otros consejos

Una pregunta hace mucho tiempo y la respuesta de @Peter es realmente elaborada. Para las personas que quieren saber cómo funciona TransferQueue en la práctica, tal vez pueda consultar la demostración en vivo a continuación.

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();
    }

}

La salida es:

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

los transfer es donde sucede la diferencia.

Transfiere el elemento a un consumidor, esperando si es necesario para hacerlo.

Más precisamente, transfiere el elemento especificado de inmediato si existe un consumidor que ya espera para recibirlo (en encuesta tomada o cronometrada), de lo contrario, espera hasta que el elemento sea recibido por un consumidor.

Como el Javadoc, el transfer Esperará hasta que el consumidor haya quitado el producto.

Esa es la razón por la cual "Producer waiting to transfer: 0" se llama en primer lugar y después de aproximadamente 2 segundos, después de haber sido recibido por el consumidor, el Producer transfered: 0 se llama entonces.

En resumen, Bloquingqueue garantiza que el elemento hecho por el productor debe estar en la cola, mientras que TransferQueue obtiene un paso más allá, garantiza que el elemento "consumido" por algún consumidor.

Aunque parece haber alguna forma de diferencia de rendimiento; ver ArrayBlockingqueue vs LinkedTransferqueue y amigos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top