Penso che il codice sorgente possa darci ulteriori indizi su come funziona. ReentrantLock.newCondition() restituisce un ConditionObject in AbstractQueuedSynchronizer .Qui è il collegamento del codice sorgente AQS source code.
1. I thread in attesa sono segnalati in ordine FIFO.
Ci sono due code in AbstractQueuedSynchronizer.
Uno è per l'attesa per il blocco (coda di basta chiamare lo scatto di attesa), vedrete due volatili variabile testa e coda nella definizione di classe AbstractQueuedSynchronizer s', e il parametro di equità influenzerà questo behavior.When della coda Sei nuovo una fiera ReentrantLock e chiamare acquisiscono, AQS chiamerà FairSync s' tryAcquire per controllare se thread corrente è il primo thread in attesa nella serratura coda in attesa, vedi hasQueuedPredecessors.
un'altra coda è la coda del segnale nella definizione di ConditionObject, vedrete due variabili firstWaiter e lastWaiter .Quando attendono si chiama, un nodo aggiungerà alla coda della coda e quando viene chiamato il segnale, un nodo dalla testina verrà rimosso dalla coda e aggiunto alla coda di attesa del blocco per riacquisire il blocco. Aggiungere alla coda di attesa blocco non significa che verrà svegliato, ma un blocco .unlock() verrà chiamato dopo il segnale , che attiverà i camerieri, vedere unparkSuccessor.
2. ordinazione di riacquisizione serratura per fili di ritorno dalla modalità di attesa è la stessa per i thread acquisire inizialmente il blocco, che è nel caso predefinito non specificato, ma per serrature equi favorisce quei fili che hanno atteso la più lunga.
svegliarsi dal attendono metodo non intendeva tenere il blocco, si chiamerà acquireQueued riacquistare la serratura e potrebbe essere parcheggiate di nuovo. Nella mia comprensione, l'ordine di acquisire inizialmente il blocco è lo stesso che l'ordine di chiamare attendono, così lo stesso come l'ordine di chiamare acquireQueued, cosa confuso me era ma per serrature equo favorisce quei fili che hanno ho aspettato il più lungo, quando svegliarsi dal attendono, a mio parere, sarà il primo thread in coda in attesa di blocco, quando chiamata acquireQueued e verificare p == testa & & tryAcquire (arg), bloccare fiera o non ha alcun effetto.
Spero che questo aiuti e lasciami se ho torto.