Stavo passando attraverso il codice sorgente di ArrayBlockingQueue e LinkedBlockingQueue. LinkedBlockingQueue ha un putLock e un takeLock rispettivamente per l'inserimento e la rimozione, ma ArrayBlockingQueue utilizza solo 1 blocco. Credo che LinkedBlockingQueue sia stato implementato in base alla progettazione descritta in Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms. In questo articolo, menzionano che mantengono un nodo fittizio in modo che gli encouer non debbano mai accedere alla testa e i dequeuers non debbano mai accedere a tail che eviti scenari di deadlock. Mi stavo chiedendo perché ArrayBlockingQueue non prende in prestito la stessa idea e usa invece 2 blocchi.ArrayBlockingQueue utilizza un unico blocco per l'inserimento e la rimozione ma LinkedBlockingQueue utilizza 2 blocchi separati
risposta
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.
Mi chiedevo perché ArrayBlockingQueue non prende in prestito la stessa idea e utilizza invece 2 blocchi.
Poiché lo ArrayBlockingQueue
utilizza una struttura dati molto più semplice per contenere gli elementi della coda.
Il ArrayBlockingQueue
memorizza i dati in un array private final E[] items;
. Affinché più thread possano gestire lo stesso spazio di archiviazione, se si aggiunge o si rimuove dalla coda, devono utilizzare lo stesso blocco. Questo non è solo a causa della barriera di memoria, ma a causa della protezione mutex poiché stanno modificando lo stesso array.
LinkedBlockingQueue
d'altra parte è un elenco collegato di elementi di coda che è completamente diverso e consente la possibilità di avere un doppio blocco. È la memoria interna degli elementi nella coda che ha abilitato le diverse configurazioni di blocco.
Penso che sia possibile per ABQ prendere in prestito la stessa idea di LBQ. Si prega di fare riferimento al mio codice http://pastebin.com/ZD1uFy7S e una domanda simile ho chiesto su SO ArrayBlockingQueue: concurrent put and take.
Il motivo per cui non l'hanno usato, è principalmente a causa della complessità nell'implementazione, in particolare gli iteratori e il compromesso tra complessità e guadagno in termini di prestazioni non era così redditizio.
Per ulteriori riferimenti si prega di dare un'occhiata a http://jsr166-concurrency.10961.n7.nabble.com/ArrayBlockingQueue-concurrent-put-and-take-tc1306.html.
2 blocchi sono utilizzati in LBQ per limitare l'accesso alla testa e bloccare contemporaneamente. Il blocco della testa non consente di rimuovere contemporaneamente due elementi e il blocco della coda non consente l'aggiunta simultanea di due elementi alla coda. i due blocchi insieme impediscono le razze.
- 1. Java: ArrayBlockingQueue vs. LinkedBlockingQueue
- 2. Quando preferire LinkedBlockingQueue su ArrayBlockingQueue?
- 3. Qual è la differenza tra ArrayBlockingQueue e LinkedBlockingQueue
- 4. SQL utilizza valori separati da virgola con la clausola IN
- 5. Nodejs con Sequelizejs che utilizza file separati per modello
- 6. scrivere per un controller che utilizza AuthComponent in CakePHP 2
- 7. Qual è la differenza tra LinkedBlockingQueue e ConcurrentLinkedQueue?
- 8. Perché Angular 2 utilizza decoratori?
- 9. utilizza lo stesso oggetto di blocco in due blocchi di codice diversi?
- 10. LinkedBlockingQueue messo vs offerta
- 11. Quale tipo di meccanismo di blocco utilizza l'istruzione di blocco
- 12. Invia() mai blocco quando si utilizza select()?
- 13. di riferimento unico errore necessaria quando si utilizza LINQ
- 14. Blocchi di blocco contro blocchi non bloccanti
- 15. Unisci due repository SVN separati in un unico repository Git
- 16. Utilizza CPU e RAM
- 17. Perché word2vec utilizza 2 rappresentazioni per ogni parola?
- 18. Perché LinkedBlockingQueue # poll() potrebbe riagganciare?
- 19. nginx: il suo multithreading ma utilizza più processi?
- 20. Come posso creare "blocchi C" quando si utilizza FFI?
- 21. Rimozione parametri dall'URL quando si utilizza Url view helper links
- 22. Se si utilizza la libreria aziendale, è meglio log4net accedere?
- 23. Json.Encode() utilizza la classe JavaScriptSerializer per serializzare
- 24. UuidCreate utilizza un CSPRNG?
- 25. Il gelsomino Gelsomino descrive blocchi annidati all'interno di un blocco
- 26. ThreadPoolExecutor con ArrayBlockingQueue
- 27. Perché l'ArrayBlockingQueue viene chiamato una coda limitata mentre un LinkedBlockingQueue viene chiamato una coda di blocco illimitata?
- 28. Utilizzando un unico modello CRUD per tutti i controller, invece di modelli separati per ogni controller
- 29. utilizza la generazione in Netbeans
- 30. rimozione citazione blocco da testo postale - Wordpress
Grazie per avermi indicato nella giusta direzione. Ho ripassato il codice e ho scoperto che sia ArrayBlockingQueue che LinkedBlockingQueue mantengono il "conteggio" della variabile. Questo è AtomicInteger in LinkedBlockingQueue (incrementato e decrementato di conseguenza in put e remove) e un int in ArrayBlockingQueue. E suppongo che non possa essere un AtomicInteger in ArrayBlockingQueue perché deve avvolgersi. – user1168577
@Peter sarebbe davvero grandioso se riuscissi a spiegare perché Two Lock Queue Algorithm non avrebbe funzionato. il conteggio può essere benissimo AtomicInteger in caso di ABQ, e l'override può essere benissimo evitato con il conteggio delle checnking == max_capacity. – veritas
@veritas Puoi spiegare dove cito l'Algoritmo Two Lock Queue? Ho scritto questo due anni fa e non riesco a trovare quello di cui stai parlando. –