2013-08-22 10 views
31
  1. Quali scenari è meglio utilizzare un oggetto ArrayBlockingQueue e quando è meglio utilizzare un oggetto LinkedBlockingQueue?
  2. Se la capacità predefinita di LinkedBlockingQueue è uguale a MAX Integer, è davvero utile utilizzarla come BlockingQueue con capacità predefinita?
+0

Per il punto n. 1, suppongo che sia esattamente la stessa ragione di ArrayList vs LinkedList;) – sp00m

+0

Un BlockingQueue non si limita a bloccare put(). Blocca anche un take(), quando la coda è vuota. –

+0

@ sp00m ma in coda non abbiamo tra l'inserimento o la cancellazione. Quindi non vi è alcuna questione di per4formance come nel caso di ArrayList e LinkedList –

risposta

17

ArrayBlockingQueue è supportato da un array la cui dimensione non cambierà mai dopo la creazione. Impostare la capacità su Integer.MAX_VALUE creerebbe un grande array con costi elevati nello spazio. ArrayBlockingQueue è sempre limitato.

LinkedBlockingQueue crea i nodi dinamicamente fino al raggiungimento dello capacity. Questo è per impostazione predefinita Integer.MAX_VALUE. L'utilizzo di una capacità così grande non ha costi aggiuntivi nello spazio. LinkedBlockingQueue è facoltativamente limitato.

12

ArrayBlockingQueue<E> e LinkedBlockingQueue<E> sono implementazioni comuni dell'interfaccia BlockingQueue<E>.

ArrayBlockingQueue è supportato da array e Queue imporre ordini come FIFO. capo della coda è l'elemento più vecchio in termini di tempo e coda della coda è l'elemento più giovane. ArrayBlockingQueue è anche buffer con dimensioni fisse con limite d'altro canto LinkedBlockingQueue è una coda con limiti facoltativi costruita in cima ai nodi collegati.

La capacità vincolato argomento opzionale costruttore serve come un modo per impedire un'espansione eccessiva coda perché se la capacità è specificato, che è uguale a Integer.MAX_VALUE.

Ulteriori informazioni Da here.

riferimento: http://www.javacodegeeks.com/2010/09/java-best-practices-queue-battle-and.html

+0

Dubito che LinkedBlockingQueue abbia un throughput più elevato. Qualche segno di restituzione del reclamo? –

+1

@EskoLuontola: è possibile trovare un punto di riferimento da qui: http://www.javacodegeeks.com/2010/09/java-best-practices-queue-battle-and.html –

+1

Così basato su tale benchmark, LinkedBlockingQueue è più veloce in scenari prodotto-consumatore, ma nei primi due benchmark ArrayBlockingQueue è leggermente più veloce. Indipendentemente da ciò, Disruptor pulisce la parola con entrambi: https://code.google.com/p/disruptor/wiki/PerformanceResults –

5

Aggiunta di un elemento di ArrayBlockingQueue si suppone essere più veloce poiché significa solamente impostando un riferimento a un elemento della matrice di supporto oggetto, mentre l'aggiunta di un elemento LinkedBlockingQueue significa creare un nodo e impostando il suo item, prev e next fields. Inoltre, quando rimuoviamo un elemento da LinkedBlockingQueue il Nodo rimosso diventa inutile, il che può influenzare le prestazioni dell'app.

Per quanto riguarda il consumo di memoria ArrayBlockingQueue mantiene sempre una matrice Object con piena capacità anche se vuota. D'altra parte un elemento in LinkedBlockingQueue è un nodo con un oggetto con 3 campi Oggetto.

+0

Questa è una buona risposta che spiega il motivo, ma hai menzionato che ArrayBlockingQueue dovrebbe essere più veloce e sono d'accordo con te in base al motivo che hai fornito. Tuttavia, Javadocs afferma che "le code collegate hanno in genere un throughput più elevato rispetto alle code basate su array, ma le prestazioni meno prevedibili nella maggior parte delle applicazioni concorrenti". vedi LinkedBlockingQueue.class – spiderman

+1

La latenza e il throughput sono 2 cose diverse.ArrayBlockingQueue ha una latenza migliore poiché è più veloce impostare il riferimento nell'array mentre LinkedBlockingQueue ha un throughput migliore poiché utilizza 2 blocchi di separazione per il put e take e si sincronizza solo sulle condizioni del bordo. –

1

ArrayBlockingQueue:

ArrayBlockingQueue è una delimitata, coda di blocco che memorizza gli elementi all'interno di un array. Il fatto che sia limitato significa che non può memorizzare quantità illimitate di elementi. C'è un limite superiore al numero di elementi che può memorizzare allo stesso tempo. Si imposta il limite superiore al momento dell'istanziazione, dopodiché non può essere modificato.

LinkedBlockingQueue

Il LinkedBlockingQueue mantiene gli elementi internamente in una struttura legata (nodi collegati). Questa struttura collegata può opzionalmente avere un limite superiore se lo si desidera. Se non viene specificato nessun limite superiore, Integer.MAX_VALUE viene utilizzato come limite superiore.

somiglianza

memorizza ArrayBlockingQueue/LinkedBlockingQueue elementi internamente in FIFO (First In First Out) ordine. Il capo della coda è l'elemento che è rimasto in coda più a lungo e la coda della coda è l'elemento che è rimasto in coda nel minor tempo possibile.

Differenze

  • LinkedBlockingQueue ha un putLock e takeLock per l'inserimento e la rimozione rispettivamente ma ArrayBlockingQueue utilizza solo 1 blocco.
  • ArrayBlockingQueue utilizza un algoritmo a doppia condizione a blocco singolo e LinkedBlockingQueue è una variante dell'algoritmo "two lock queue" e presenta 2 condizioni di lock 2 (takeLock, putLock).

Due algoritmo di blocco della coda è utilizzato da assumere e mettere di LinkedBlockingQueue Implementation.Thus LinkedBlockingQueue in grado di lavorare contemporaneamente, ma questo non è il caso di ArrayBlockingQueue. Il motivo dell'utilizzo di un singolo blocco in ArrayBlockingQueue è che ArrayBlockingQueue deve evitare di sovrascrivere le voci in modo che sia necessario sapere dove si trova l'inizio e la fine. Un LinkedBlockQueue non ha bisogno di saperlo poiché lascia che il GC si preoccupi di ripulire i nodi nella coda.

Problemi correlati