2010-03-19 8 views
7

Java 6 API Frage. Ruft LockSupport.unpark(thread) eine passiert vor Beziehung auf die Rückkehr von LockSupport.park in den gerade entparkten Thread? Ich vermute stark die Antwort ist ja, aber der Javadoc scheint es nicht explizit zu erwähnen.Java LockSupport Speicherkonsistenz

Antwort

1

Ich habe den JDK-Code angeschaut und es sieht so aus, als ob LockSupport-Methoden normalerweise außerhalb von Synchronisationsblöcken aufgerufen werden. Ihre Annahme scheint also korrekt zu sein.

+1

Es tut uns leid, eine so alte Antwort kommentieren zu müssen, aber da die Frage die Java * API * und nicht die * Implementierung von Sun/Oracle ist, ist die Analyse des JDK 'LockSupport' nicht 100% korrekt. Die JDK-Entwickler können Annahmen über ihre eigene Implementierung treffen, während eine portable Anwendung dies nicht tun sollte. Darüber hinaus gibt es Möglichkeiten, eine * happen-before * -Beziehung zu erreichen, die keine "synchronisierten" Blöcke enthält. – rolve

+0

"... durch den JDK Code geschaut": Können Sie bitte eine hg URL für OpenJDK posten? – kevinarpe

5

Wenn es nicht als solches dokumentiert ist, dann können Sie sich NICHT darauf verlassen, dass es eine Situation vor der Beziehung erzeugt.

Speziell LockSupport.java im Hotspot-Code ruft einfach Unsafe.park und .unpark!

Die passiert vor Beziehung wird in der Regel von einem Schreib-Lese-Paar auf einem flüchtigen Statusflag oder etwas Ähnliches kommen.

Denken Sie daran, wenn es nicht als Schaffung eines passiert-vor Beziehung Sie müssen dann dokumentiert es behandeln, als ob es auch dann nicht, wenn Sie nachweisen können, dass es auf Ihrem spezifischen System der Fall ist. Zukünftige Systeme und Implementierungen möglicherweise nicht. Sie haben sich aus gutem Grund diese Freiheit gelassen.

6

Ich habe gerade diese Frage gefunden, weil ich mich das gleiche gefragt habe. Nach this article von Oracle Forscher David Dice, scheint die Antwort keine zu sein. Hier ist der relevante Teil des Artikels:

Wenn ein Thread in park() blockiert wir garantiert, dass eine nachfolgende unpark() wird es bereit machen. Eine vollkommen legale aber Implementierung von park() und unpark() wäre leere Methoden, in denen das Programm zum einfachen Spinnerei degeneriert. In der Tat ist das der Lackmustest für korrekte park() - unpark() Verwendung.

Leere park() und unpark() Methoden geben Sie keine passiert-vor Beziehung garantiert, so dass für das Programm 100% tragbar sein, sollten Sie nicht auf sie verlassen.

Dann wieder, die Javadoc of LockSupport sagt:

Diese Methoden als Werkzeuge verwendet werden sollen, die für die Erstellung geordnete Synchronisation Dienstprogramme und sind in sich nicht für die meisten Concurrency Control-Anwendungen nützlich. Die park Methode ist nur zur Verwendung in Konstruktionen der Form:

while (!canProceed()) { ... LockSupport.park(this); }

Da Sie müssen explizit ohnehin eine Bedingung überprüfen, die entweder volatile oder richtig synchronisierten Variablen beinhalten wird, die schwachen Garantien park() sollte eigentlich kein Problem sein, oder?

+2

Danke für diese Antwort. Ich kann mich nicht erinnern, warum ich das wissen wollte. Ich vermute, ich frage mich, ob, wenn der laufende Thread die Bedingung aktualisiert und 'entparken' genannt hat, würde das, wenn dies selbst den nicht entparkt Thread garantieren würde, die aktualisierte Bedingung in einem konsistenten Zustand sehen. Es scheint, dass es keine Garantie gibt, also ist die einzige sichere Wahl, eine Speicherbarriere für die Zustandsaktualisierung explizit anzuordnen. – Lachlan

+0

Ich verstehe. Wenn es eine * happen-before-Beziehung zwischen "park()" und "unpark()" gäbe, müsste die Bedingung keine Speicherbarriere beinhalten. Die Frage ist also immer noch gültig. – rolve