Question

Je suis un peu confus quant à ce que la différence entre BlockingQueue / LinkedBlockingQueue et le nouveau TransferQueue / types LinkedTransferQueue de jsr166y et java 7

Était-ce utile?

La solution

De TransferQueue JavaDocs :

BlockingQueue où les producteurs peuvent attendre les consommateurs de recevoir des éléments. Un TransferQueue peut être utile, par exemple dans les applications passant de message dans lequel les producteurs parfois (par transfert de méthode (E)) réception await des éléments par les consommateurs invoquant prendre ou un sondage, d'autres fois ENQUEUE éléments (par mettre la méthode) sans attendre la réception.

En d'autres termes, lorsque vous utilisez BlockingQueue, vous ne pouvez élément mis en file d'attente (et bloc si la file d'attente est pleine). Avec TransferQueue, vous pouvez également bloquer jusqu'à ce qu'un autre fil reçoit votre élément (vous devez utiliser une nouvelle méthode transfer pour cela). C'est la différence. Avec BlockingQueue, vous ne pouvez pas attendre autre thread supprime votre élément (uniquement lorsque vous utilisez SynchronousQueue, mais ce n'est pas vraiment une file d'attente).

Autre que cela, TransferQueue est aussi un BlockingQueue. Découvrez de nouvelles méthodes disponibles dans TransferQueue: http: / /download.oracle.com/javase/7/docs/api/java/util/concurrent/TransferQueue.html (transfert, tryTransfer, hasWaitingConsumer, getWaitingConsumerCount).


Collections Améliorations apportées au cadre en Java SE 7 dit explicitement:

Le TransferQueue d'interface a été ajoutée. Il est un raffinement de l'interface BlockingQueue dans laquelle les producteurs peuvent attendre les consommateurs de recevoir des éléments. Une mise en œuvre de la nouvelle interface est également inclus dans cette version, LinkedTransferQueue.

Autres conseils

Il y a longtemps question et @ la réponse de Pierre est vraiment élaborer. Pour les personnes qui veulent savoir comment TransferQueue fonctionne dans la pratique, vous pouvez peut-être se référer à la démonstration en direct ci-dessous.

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 sortie est:

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

Le transfer est où la différence se produit.

Transfert l'élément à un consommateur, en attendant si nécessaire de le faire.

Plus précisément, transfère l'élément spécifié immédiatement en cas existe un consommateur attend déjà de le recevoir (en prendre ou chronométré sondage), attend d'autre jusqu'à ce que l'élément est reçu par un consommateur.

Comme le javadoc, l'transfer attendra jusqu'à ce que le consommateur a enlevé le produit.

C'est la raison pour laquelle "Producer waiting to transfer: 0" est appelée d'abord et après environ 2 secondes, après avoir été reçu par le consommateur, le Producer transfered: 0 est appelé alors.

En bref, BlockingQueue garantit que l'élément fabriqué par le producteur doit être dans la file d'attente, alors que TransferQueue obtient un peu plus loin, il garantit que l'élément « consommé » par certains consommateurs.

Bien qu'il ne semble y avoir une certaine forme de différence de performance; voir ArrayBlockingQueue vs LinkedTransferQueue et les amis

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top