Così scavare attraverso le viscere della sorgente di Java 6 (saltare la parte tra le regole orizzontali, se non si cura di trovare il codice vero responsabile di questa roba)
La classe
java.util.concurrent.LinkedBlockingQueue
implementa mutex usando istanze di
java.util.concurrent.locks.ReentrantLock
.
A sua volta, le variabili di sincronizzazione vengono generate utilizzando java.util.concurrent.locks.ReentrantLock.newCondition()
che chiama java.util.concurrent.locks.ReentrantLock$Sync.newCondition()
.
Procedimento java.util.concurrent.locks.ReentrantLock$Sync.newCondition()
restituisce un'istanza di java.util.concurrent.AbstractQueuedSynchronizer$ConditionObject
che implementa le normali chiamate variabili sincronizzazione a await()
, signal()
e signalAll()
descritte dall'interfaccia java.util.concurrent.locks.Condiion
.
Guardando il codice sorgente per la classe ConditionObject
, che mantiene due membri chiamati firstWaiter
e lastWaiter
che sono i primi e gli ultimi nodi in una coda di blocco CLH (istanze di java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
).
La documentazione a che gli stati di classe:
Un thread può cercare di acquisire se è primo in coda. Ma essere i primi non garantisce il successo; dà solo il diritto di contendere. Pertanto, il thread di concorrenti attualmente rilasciato potrebbe dover essere nuovamente visualizzato.
Così Credo che la risposta è che il metodo take()
in LinkedBlockingQueue
tentativi di dare un trattamento preferenziale a quelle thread che chiama take()
in precedenza. Fornirà il primo thread per chiamare take()
la prima possibilità di catturare un oggetto di coda quando diventa disponibile, ma a causa di timeout, interruzioni, ecc. Che thread non è garantito essere il primo thread per rimuovere l'elemento dal coda.
Ricordare che questo è completamente specifico per questa particolare implementazione. In generale, si dovrebbe supporre che le chiamate a take()
si sveglieranno un thread di attesa casuale quando un elemento di coda diventa disponibile e non necessariamente il primo che ha chiamato take()
.
fonte
2010-07-26 22:20:19