"Nichts" tun, während "Zustand"
Beim Browsen der code für die Java-8-version der ForkJoinPool(die hat ein paar interessante änderungen ab Java 7) lief ich über dieses Konstrukt (hier):
do {} while (!blocker.isReleasable() &&
!blocker.block());
Bin ich mit zu kämpfen, warum schreiben Sie es so, statt nur
while (!blocker.isReleasable() &&
!blocker.block());
Ist es nur Semantik/Lesbarkeit Wahl, da Sie Lesen konnte, das erste Konstrukt, das als do "nothing" while "conditions"
? Oder gibt es einige zusätzliche Vorteile, die ich bin fehlt?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie Lesen Sie die Kommentare am Anfang der Datei, direkt unter der Deklaration der Klasse, es ist ein Abschnitt, der erklärt, die Verwendung dieses Konstrukts:
while
version?do {} while()
vermeidet JIT-Optimierung, diewhile()
verwendet. Die while-Anweisungen sind semantisch äquivalent, so muß die Differenz werden in der Implementierung der JVM.while
Schleife verwendet wurde überhaupt. Ich denke, die Gründe sind eher diejenigen, die in der Antwort von Erik Vesteraas, nämlich 1. Klarheit und Lesbarkeit (!) und 2. Kleiner bytecode (1 byte 1 byte).ForkJoinPool
macht umfangreichen Gebrauch voncompareAndSwap...
aussun.misc.Unsafe
und die meisten vorkommen vondo {} while (...)
imForkJoinPool
können — wie bereits von anderen Antworten werden erklärt sich durch diesen Kommentar unter der Rubrik Stil Hinweise:Die Wahl zu verwenden, schreiben Sie eine
while
-Schleife mit einer leeren Körper alsdo {} while (condition)
scheint jedoch zu sein, meist stilistische Wahl. Dies ist vielleicht klarer inHashMap
,, die passiert werden aktualisiert in Java 8.In der Java 7
HashMap
Sie finden diese:Während viel code, um ihn herum hat sich verändert, es ist klar, dass der Ersatz in Java 8 ist diese:
Die erste version hat die Schwäche, dass, wenn der einsame Semikolon passiert gelöscht werden, es würde sich ändern, die Bedeutung des Programms, je nach der folgenden Zeile.
Wie unten zu sehen ist, bytecode generiert
while (...) {}
unddo {} while (...);
ist etwas anders, aber nicht in irgendeiner Art und Weise auswirken sollte nichts beim ausführen.Java-code:
Generierten code:
Abgesehen jeder potentielle performance-Vorteile, es gibt eine klare Lesbarkeit profitieren.
Mit
while (X) ;
das nachgestellte Semikolon ist nicht immer auf den ersten Blick erkennbar, Sie können verwechselt werden, zu denken, dass die folgende Anweisung oder Anweisungen innerhalb der Schleife. Zum Beispiel:Wäre es sehr leicht falsch verstanden, die oben als mit der if-Anweisung innerhalb der Schleife, und auch wenn Sie haben richtig gelesen, es wäre einfach zu denken, dass es war ein Programmier-Fehler und die wenn sollte innerhalb der Schleife.
Mit
do {} while(X);
wenn es sofort auf einen Blick klar, dass es keinen Körper der Schleife.while (x==process(y)) {}
? Ich denke, dass wäre fast so klar wie dasdo ... while()
Lösung.do {} while
Bau keywords zwischen den Klammern, es macht die Trennung sauberer. Selbst in diesem einfachen Beispiel haben wir bereits 4 Klammern nach jeder anderen)){}
- Sie kann leicht sehen, dass diese Zahl erhöhen könnte, als wenn immer mehr kompliziert...so ist es einfacher, einfach nicht beachten die{}
mit all den anderen.Wenn Sie Lesen Kommentar über dem code, Es wird erwähnt, dass...
Wenn der Anrufer nicht eine
ForkJoinTask
diese Methode ist behaviorally equivalent zuSo ist es nur eine andere form zu implementieren Sie obigen code in den else-Teil...!!
In Style notes es wird erwähnt, dass,
Und wenn Sie sehen die Umsetzung von ManagedLocker#isReleasable, Es ist die Aktualisierung der Schleuse und zurück
true
wenn blockieren unnötig ist.Interpretation :
Leere while-Schleifen werden verwendet, um ein unterbrechen, bis eine Bedingung reset auf true/false.
Hier
do { } while(!...)
ist ein blocker/unterbrechen, bisblocker.block()
wirdtrue
wennblocker.isReleasable()
istfalse
. Schleife wird die Ausführung fortsetzen, währendblocker
ist nicht lösbare (!blocker.isReleasable()
) undblocker
ist nicht gesperrt!!!! Die Ausführung wird aus der Schleife, sobaldblocker.block()
wird auf true gesetzt.Beachten Sie, dass
do{ } while(...)
nicht aktualisiert CAS-variable, aber Sie garantieren, dass das Programm wartet, bis die variable aktualisiert wird (Kraft, zu warten, bis die variable aktualisiert wird).while(!cas...)
wäre nicht eine Aktualisierung erzwingen? Dass es eine eigentliche technische Unterschied, wie gezeigt, durch den bytecode? Ich bin Anfang zu Fragen, wenn man isReleasable ist eine Ablenkung, denn es gibt viele Orte, wo es verwendet wird, für die tatsächliche CAS-Variablen wie diese:do {} while (!U.compareAndSwapLong(...));
isReleasable()
ist eine Ablenkung, Siehe die interpretation Bearbeiten.while(!cas...);
wäre in der Lage zu zwingen, ein update auf eine CompareAndSwap-variable, oder, wenndo {} while (!cas...);
notwendig ist, d.h., ob es einen technischen Unterschied oder nicht.do{}
aktivieren Sie diese unterbrechen?do{}while(...)
ermöglicht unterbrechen, es kann getan werden, mitwhile() { }
auch. und bei den byte-code finden Sie Eriks Antwort, in diesem Muster weiteregoto
ist nicht erforderlich, daifeq
Anleitung gibt es stattifne
... ich habe nie gesagt, nurdo{}
werden verwendet, um interrupt !! 😉 😀while(...);
unddo{}while(...);
im byte-code. Nur ein unbedingter Sprung weniger.Können Sie ganz einfach machen, so etwas mit: