Domanda

Sono un po 'confuso su ciò che è la differenza tra BlockingQueue / LinkedBlockingQueue e il nuovo TransferQueue / tipi LinkedTransferQueue da jsr166y e Java 7

È stato utile?

Soluzione

TransferQueue JavaDocs :

Un BlockingQueue in cui i produttori possono aspettare che i consumatori di ricevere elementi. Un TransferQueue può essere utile ad esempio nelle applicazioni di messaggi in cui i produttori a volte (Procedimento di trasferimento (E)) il ricevimento Await di elementi da parte dei consumatori invocando take or sondaggio, mentre altre volte Enqueue elementi (tramite metodo put) senza attendere per il ricevimento.

In altre parole, quando si utilizza BlockingQueue, si può solo mettere elemento nella coda (e blocco se coda è piena). Con TransferQueue, è anche possibile bloccare fino a quando altri thread riceve il vostro elemento (è necessario utilizzare nuovo metodo transfer per questo). Questa è la differenza. Con BlockingQueue, non si può aspettare fino a quando un altro thread rimuove il vostro elemento (solo quando si utilizza SynchronousQueue, ma che non è in realtà una coda).

Oltre a questo, è anche un TransferQueue BlockingQueue. Scopri i nuovi metodi disponibili in TransferQueue: http: / /download.oracle.com/javase/7/docs/api/java/util/concurrent/TransferQueue.html (trasferimento, tryTransfer, hasWaitingConsumer, getWaitingConsumerCount).


Collezioni quadro Miglioramenti in Java SE 7 dice esplicitamente:

È stata aggiunta la TransferQueue interfaccia. Si tratta di un perfezionamento dell'interfaccia BlockingQueue in cui i produttori possono aspettare per i consumatori di ricevere elementi. Un'implementazione della nuova interfaccia è anche incluso in questa versione, LinkedTransferQueue.

Altri suggerimenti

Una domanda molto tempo fa e @ risposta di Pietro è davvero elaborati. Per le persone che vogliono sapere come funziona TransferQueue in pratica, forse si può fare riferimento alla demo live qui sotto.

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

}

L'output è:

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

Il transfer è dove la differenza succede.

Trasferisce l'elemento ad un consumatore, in attesa, se necessario, per farlo.

Più precisamente, trasferisce l'elemento specificato immediatamente se ci esiste un consumatore già in attesa di ricevere (in prendere o temporizzato sondaggio), attende altro finché l'elemento viene ricevuto da un consumatore.

Mentre il javadoc, il transfer attenderà fino a quando il consumatore ha preso il prodotto lontano.

Questo è il motivo per cui "Producer waiting to transfer: 0" è chiamato in primo luogo e dopo circa 2 secondi, dopo che è stato ricevuto da parte del consumatore, il Producer transfered: 0 è chiamato quindi.

In breve, BlockingQueue garantisce che l'elemento di fatto da produttore deve essere in coda, mentre TransferQueue ottiene un ulteriore passo avanti, garantisce che l'elemento "consumato" da parte di alcuni consumatori.

Anche se ci sembra essere una qualche forma di differenza di prestazioni; vedi ArrayBlockingQueue vs LinkedTransferQueue e gli amici

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top