Frage

Ich bin etwas verwirrt darüber, was der Unterschied zwischen BlockingQueue/LinkedBlockingQueue und den neuen TransferQueue/LinkedTransferQueue-Typen von jsr166y und Java 7 ist

War es hilfreich?

Lösung

Aus TransferQueue JavaDocs:

Eine BlockingQueue, in der Produzenten darauf warten können, dass Verbraucher Elemente erhalten.Eine TransferQueue kann beispielsweise in Nachrichtenübermittlungsanwendungen nützlich sein, in denen Produzenten manchmal (mit der Methode transfer(E)) auf den Empfang von Elementen durch Verbraucher warten, die take oder poll aufrufen, während sie zu anderen Zeiten Elemente in die Warteschlange stellen (über die Methode put), ohne auf den Empfang zu warten.

Mit anderen Worten: Wenn Sie BlockingQueue verwenden, können Sie Elemente nur in die Warteschlange stellen (und blockieren, wenn die Warteschlange voll ist).Mit TransferQueue können Sie auch blockieren, bis ein anderer Thread Ihr Element empfängt (Sie müssen new verwenden transfer Methode dafür).Das ist der Unterschied.Mit BlockingQueue können Sie nicht warten, bis ein anderer Thread Ihr Element entfernt (nur wenn Sie SynchronousQueue verwenden, aber das ist nicht wirklich eine Warteschlange).

Darüber hinaus ist TransferQueue auch eine BlockingQueue.Schauen Sie sich die neuen verfügbaren Methoden in TransferQueue an: http://download.oracle.com/javase/7/docs/api/java/util/concurrent/TransferQueue.html (transfer, tryTransfer, hasWaitingConsumer, getWaitingConsumerCount).


Verbesserungen des Collections Framework in Java SE 7 sagt ausdrücklich:

Die Schnittstelle TransferQueue wurde hinzugefügt.Es handelt sich um eine Weiterentwicklung der BlockingQueue-Schnittstelle, bei der Produzenten darauf warten können, dass Konsumenten Elemente erhalten.Eine Implementierung der neuen Schnittstelle ist ebenfalls in dieser Version enthalten, LinkedTransferQueue.

Andere Tipps

Eine Frage vor langer Zeit und @Peters Antwort ist wirklich ausführlich. Für Menschen, die wissen möchten, wie Transferqueue in der Praxis funktioniert, können Sie sich vielleicht auf die Live -Demo verweisen.

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

}

Die Ausgabe ist:

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

Das transfer ist wo der Unterschied passiert.

Überträgt das Element an einen Verbraucher und wartet, falls erforderlich, dies zu tun.

Genauer gesagt überträgt das angegebene Element sofort, wenn ein Verbraucher bereits darauf wartet, es zu erhalten (in Take oder Timed Poll), sonst wartet, bis das Element von einem Verbraucher eingeht.

Als Javadoc die transfer Warte, bis der Verbraucher das Produkt weggenommen hat.

Das ist der Grund, warum "Producer waiting to transfer: 0" wird zuerst bezeichnet und nach ungefähr 2 Sekunden, nachdem es vom Verbraucher eingegangen ist, die Producer transfered: 0 wird dann genannt.

Kurz gesagt, Blockingqueue garantiert, dass sich das von Produzent hergestellte Element in der Warteschlange befinden muss, während Transferqueueue noch einen Schritt weiter geht, es garantiert, dass das von einem Verbraucher "konsumierte" Element "konsumiert".

Obwohl es eine Form des Leistungsunterschieds zu geben scheint; sehen ArrayBlockingQueue gegen LinkedTransferqueue und Freunde

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top