Der Punkt der SynchronousQueue
ist, etwas zu synchronisieren, das normalerweise ziemlich asynchron ist - ein Thread, der ein Element in die Warteschlange legt, während ein anderes versucht, davon zu nehmen.
Die SynchronousQueue
ist eigentlich gar keine Warteschlange. Es hat keine Kapazität, keinen internen Speicher. Es kann nur aus der Warteschlange genommen werden, wenn ein anderer Prozess gerade versucht, sich in die Warteschlange einzufügen.
Beispiel:
Verfahren A versucht, in die Warteschlange zu stellen. Dies blockiert für jetzt. Prozess B versucht, aus der Warteschlange zu nehmen. Da jemand versucht zu setzen, wird der Gegenstand von A nach B transferiert, und beide werden entsperrt.
Prozess B versucht, aus der Warteschlange zu nehmen, aber niemand versucht zu setzen. Also B ist jetzt blockiert. Der Prozess A möchte jetzt einen Artikel einfügen. Jetzt wird der Artikel an B übertragen und A und B werden nicht mehr blockiert.
Über die Sperrung:
The Sun/Oracle JRE Implementierung Polling nicht verwendet anstelle eines Warte/notify Muster, wenn Sie eine Zeitbetrieb zu tun (wie „versuchen, für 1 Sekunde nehmen“). Das macht Sinn: Es wiederholt sich periodisch, bis die Zeit abgelaufen ist. Wenn Sie eine nicht zeitgesteuerte Operation ausführen (wie "Take, egal wie lange es dauert"), verwendet es park
, was wieder wacht, wenn sich die Situation geändert hat. In keiner Situation wäre einer Ihrer Cores ständig damit beschäftigt, eine Schleife zu drehen for (;;)
bedeutet "Wiederholen unbestimmt" in diesem Fall, bedeutet es nicht "konstantes Spinnen".
Das ist die Grundlage von Lock-Free-Algorithmen - beachten Sie, dass das Spinnen nur erfolgt, wenn etwas zu übertragen ist Die Übertragung erfolgt, oder wenn nichts zu tun ist, kehrt die Methode zurück: – assylias
@assylias: In den meisten Teilen von 'TransferQueue.transferer' gibt es ein' continue' nicht ein 'return'. In einigen Fällen gibt es eine Rückgabe Fall ich habe keine Ahnung, was mit den Kellnern passiert und wann/wie sie neu starten – Jim