5

Ich habe versucht, die Implementierung von Synchronous Queue
zu lesen Es ist nicht so einfach für mich. Es scheint eine verknüpfte Liste zu verwenden, in der jeder Knoten einem Thread zugeordnet ist.
Und der Kernteil verwendet eine Spin-Schleife, die darauf wartet, dass Aufgaben in die Warteschlange gestellt werden.
Ich frage mich, warum eine Spin-Schleife anstelle von etwas wie wait/notify verwendet wird?
Jetzt ist einer der Kerne wegen dieser konstanten Spin-Schleife weg, oder?
Ich versuche, diesen Punkt zu verstehen und ein grobes Verständnis der Gestaltung der Synchron QueueVersucht, die Mechanik einer synchronen Warteschlange zu verstehen

UPDATE
Was auch mir ist beunruhigend ist erhalten, wie die Kellner Threads starten/stoppen.

+0

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

+0

@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

Antwort

4

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".

+0

Ich denke, dass es keine tatsächliche Blockierung gibt. Ich meine, der Blockierungsteil wird über implementiert eine Spin-Schleife. Diese Schleife "isst" CPU-Zyklen. Warum wurde die Blockierung nicht durch irgendeine Form von "Warten" oder "Schlafen" implementiert? – Jim

+0

Du denkst falsch, dann ;-) Da ist Blockieren. Aus diesem Grund öffnet das verknüpfte API-Dokument den Satz "Eine blockierende Warteschlange, in der jeder Einfügevorgang auf einen entsprechenden Löschvorgang durch einen anderen Thread warten muss, und umgekehrt." –

+1

Aber Sie zitieren den Javadoc.Ich habe bereits erwähnt Ich habe versucht, die Implementierung zu verstehen, in der ich 'for (;;) {' in der Implementierung von 'transfer' gefunden habe. – Jim