Questa domanda merita una risposta migliore.
Java ConcurrentLinkedQueue
si basa sulle famose code algorithm by Maged M. Michael and Michael L. Scott per non-blocking lock-free.
"Non bloccante" come termine qui per una risorsa contesa (la nostra coda) significa che indipendentemente da ciò che fa lo scheduler della piattaforma, come interrompere un thread, o se il thread in questione è semplicemente troppo lento, altri thread contendono per la stessa risorsa sarà ancora in grado di progredire. Ad esempio, se un blocco è coinvolto, il thread che blocca il blocco potrebbe essere interrotto e tutti i thread in attesa di quel blocco sarebbero bloccati. I blocchi intrinseci (la parola chiave synchronized
) in Java possono anche avere una penalità severa per le prestazioni, ad esempio quando è implicato biased locking e si dispone di contesa, oppure dopo che la VM decide di "gonfiare" il blocco dopo un periodo di tolleranza di rotazione e bloccare i thread concorrenti ... che è il motivo per cui in molti contesti (scenari di contesa basso/medio), fare confronti e insiemi su riferimenti atomici può essere molto più efficiente e questo è esattamente ciò che stanno facendo molte strutture di dati non bloccanti.
Java ConcurrentLinkedQueue
non è solo non bloccante, ma ha la proprietà eccezionale che il produttore non contende con il consumatore. In un singolo produttore/scenario singolo consumatore (SPSC), questo significa davvero che non ci sarà alcuna contesa di cui parlare. In uno scenario a più produttori/consumatori singoli, il consumatore non contenderà i produttori. Questa coda ha contesa quando più produttori provano a offer()
, ma questa è la concorrenza per definizione. È fondamentalmente uno scopo generale ed efficiente coda non bloccante.
Per quanto non sia un BlockingQueue
, beh, bloccare un thread per attendere su una coda è un modo terribilmente terribile di progettare sistemi concorrenti. Non farlo. Se non riesci a capire come utilizzare uno ConcurrentLinkedQueue
in uno scenario consumatore/produttore, passa semplicemente alle astrazioni di livello superiore, come un buon framework per attori.
fonte
2014-06-26 20:43:29
Grazie Jon - non avevo notato. Quindi, dove/perché dovresti usare ConcurrentLinkedQueue? – Adamski
Quando è necessario accedere alla coda da molti thread, ma non è necessario "attendere" su di esso. –
Un 'ConcurrentLinkedQueue' è anche utile se il thread sta controllando più code. Ad esempio, in un server multi-tenant. Supponendo che per ragioni di isolamento non si usi una singola coda di blocco e un discriminatore di inquilino. – LateralFractal