2012-08-06 12 views
5

Per quanto ne so, sia la lista collegata che la matrice possono crescere senza limiti o sbaglio? Ma quando ho attraversato il documentation in the Executor Service vedo questo:Perché l'ArrayBlockingQueue viene chiamato una coda limitata mentre un LinkedBlockingQueue viene chiamato una coda di blocco illimitata?

Code illimitate. L'utilizzo di una coda illimitata (ad esempio un valore LinkedBlockingQueue senza una capacità predefinita) causerà l'attesa di nuove attività nella coda quando tutti i thread corePoolSize sono occupati. Quindi, non verranno mai creati più di corePoolSize. (E il valore del maximumPoolSize pertanto non ha alcun effetto.)

così fa il Unbounded Queue modifiche alle proprietà quando il LinkedBlockingQueue ha una capacità definita?

E questo scritto per ArrayBlockingQueue:

code delimitate. Una coda limitata (ad esempio, ArrayBlockingQueue) aiuta a prevenire l'esaurimento delle risorse quando viene utilizzata con un numero finito di MaximumPoolSizes, ma può essere più difficile da regolare e controllare. Coda le dimensioni e le dimensioni massime del pool possono essere scambiate l'una per l'altra: l'uso di code e piccoli pool di grandi dimensioni riduce al minimo l'utilizzo della CPU, le risorse del sistema operativo e il sovraccarico di commutazione del contesto , ma può comportare un throughput artificiosamente basso. . Se le attività si bloccano frequentemente (ad esempio se sono collegate I/O ), un sistema può essere in grado di pianificare il tempo per più thread di altrimenti consentito. L'utilizzo di code di piccole dimensioni richiede generalmente dimensioni di pool più grandi, che mantengono le CPU più occupate ma potrebbero verificarsi un sovraccarico di pianificazione inaccettabile, che riduce anche il throughput.

risposta

7

Perché pensi che un ArrayBlockingQueue possa crescere senza limiti? Dalla sua own documentation:

Questo è un classico "delimitata tampone", in cui una matrice fissa dimensioni contiene elementi inseriti dai produttori e estratte dai consumatori. Una volta creata, la capacità non può essere aumentata. I tentativi di mettere un elemento in una coda completa comporteranno il blocco dell'operazione; i tentativi di prendere un elemento da una coda vuota verranno bloccati allo stesso modo.

In altre parole, una volta pieno, è pieno, non cresce.

Ti stai confondendo con un ArrayList per caso, che è anche supportato da un array, ma che espande questo come richiesto?

Così la proprietà Coda illimitata cambia quando LinkedBlockingQueue ha una capacità definita?

Sì, quindi perché è descritto come "facoltativamente limitato" nel suo Javadocs. Inoltre, i documenti dichiarano che (sottolineatura mia):

L'argomento del costruttore di capacità associato facoltativo serve come modo per impedire un'espansione eccessiva della coda. La capacità, se non specificata, è uguale a Integer.MAX_VALUE.I nodi collegati vengono creati dinamicamente ad ogni inserimento a meno che ciò non porti la coda sopra la capacità.

+0

@Andrej Sì, sto confondendo ArrayList per Array. grazie per il chiarimento. A proposito di come cresce ArrayList quando è supportato da un array sottostante che non può crescere? – Geek

+4

Quando è necessario ridimensionare, 'ArrayList' alloca una nuova matrice più grande e copia tutti gli elementi in quella nuova matrice. –

2

Per quanto ne so sia la lista collegata e array possono crescere senza limiti o mi sbaglio

Una lista concatenata come una dimensione illimitata. Un array ha dimensioni fisse. Un ArrayList avvolge un array e lo sostituisce quando ne ha bisogno uno più grande.

così fa il illimitate modifiche alle proprietà della coda quando il LinkedBlockingQueue ha una capacità definita

Quando LinkedBlockingQueue ha una capacità massima, è delimitata ma non usato in questo modo per impostazione predefinita.

+1

"Un ArrayList esegue il wrapping di un array sostituendolo quando necessita di uno più grande." Puoi vedere questo nel metodo ensureCapacity per ArrayList. –

3

Dal documentataion per ArrayBlockingQueue

Un delimitata blocco coda sostenuta da un array. Questa coda ordina elementi FIFO (first-in-first-out). Il capo della coda è quell'elemento che è rimasto in coda più a lungo. La coda della coda è quell'elemento che è rimasto in coda nel minor tempo possibile. I nuovi elementi vengono inseriti alla coda della coda e le operazioni di recupero della coda ottengono gli elementi in testa alla coda.

Se si nota che tutti i costruttori di ArrayBlockingQueue prendono una capacità perché questa classe è stata progettata per essere limitata. Questa scelta è stata fatta perché se si desidera una coda concorrente, probabilmente non si desidera il sovraccarico dovuto al ridimensionamento di una ArrayList. Quindi, se si desidera una coda illimitata, LinkedBlockingQueue è un'opzione migliore poiché non comporta questo sovraccarico.

2

Il javadoc for LinkedBlockingQueue dice:

Una coda bloccando opzionalmente-delimitata sulla base di nodi connessi [...]

La capacità opzionale argomento del costruttore legato serve come un modo per evitare un'eccessiva espansione coda. . La capacità, se non specificata, è uguale a Integer.MAX_VALUE.

Il javadoc of ArrayBlockingQueue dice:

Un delimitata blocco coda sostenuta da una serie [...]

Questo è un classico "delimitata buffer", in cui un array di dimensioni fisse. detiene gli elementi inseriti dai produttori ed estratti dai consumatori. Una volta creato , la capacità non può essere aumentata

Quindi, una coda di blocco collegato può essere delimitata ou sconfinata, mentre un ArrayBlockingQueue è sempre limitato.

0

altra risposta è molto giusto! Fornisco un altro modo per spiegare. beh, anch'io mi sento confuso dal termine "non legato e rilegato" passato. puoi guardare il codice sorgente soffiato.

/** The queued items */ 
final Object[] items; 

/** items index for next take, poll, peek or remove */ 
int takeIndex; 

/** items index for next put, offer, or add */ 
int putIndex; 

/** Number of elements in the queue */ 
int count; 

dal codice sorgente, possiamo vedere la matrice è finale, quindi non possiamo ridimensionare la matrice. se usi LinkedBlockingQueue, possiamo sempre aggiungere più elementi ... e nel codice sorgente, il riferimento successivo non è definitivo. NOTA, in teoria, LinkedBlockingQueue non è illimitato. perché può memorizzare MAX_INTEGER meno 8 elementi. da javadoc, la coda illimitata è PriorityBlockingQueue. ma il PriorityBlockingQueue può anche memorizzare MAX_INTEGER -8 elementi. quindi penso che non ci sia una coda illimitata perfetta ...

Problemi correlati