801 Stimmen

Wofür ist das Schlüsselwort volatile nützlich?

Bei der Arbeit stieß ich heute auf die volatile Schlüsselwort in Java. Da ich damit nicht sehr vertraut bin, fand ich diese Erklärung .

Wenn man bedenkt, wie detailliert in diesem Artikel das betreffende Schlüsselwort erklärt wird, haben Sie es dann jemals verwendet oder könnten Sie sich einen Fall vorstellen, in dem Sie dieses Schlüsselwort auf die richtige Art und Weise verwenden könnten?

31voto

Dave L. Punkte 42559

Ein gängiges Beispiel für die Verwendung volatile ist die Verwendung eines volatile boolean als Flagge zum Beenden eines Threads. Wenn Sie einen Thread gestartet haben und ihn sicher von einem anderen Thread aus unterbrechen wollen, können Sie den Thread periodisch ein Flag überprüfen lassen. Um ihn zu beenden, setzen Sie das Flag auf true. Indem Sie das Flag volatile können Sie sicherstellen, dass der Thread, der sie prüft, bei der nächsten Prüfung sieht, dass sie gesetzt wurde, ohne dass Sie eine synchronized Block.

16voto

yoAlex5 Punkte 20661

Flüchtig

volatile -> synchronized [Über]

volatile besagt für einen Programmierer, dass der Wert immer aktuell sein wird. Das Problem ist, dass der Wert in verschiedenen Arten von Hardwarespeicher gespeichert werden kann. Es kann sich zum Beispiel um CPU-Register, CPU-Cache, RAM... handeln. PU-Register und CPU-Cache gehören zur CPU und können keine Daten gemeinsam nutzen, im Gegensatz zum RAM, der in einer Multithreading-Umgebung die Rettung ist.

enter image description here

volatile Schlüsselwort besagt, dass eine Variable gelesen und geschrieben vom/zum RAM-Speicher direkt . Sie hat einen gewissen Rechenaufwand

Java 5 erweitert volatile durch Unterstützung happens-before [Über]

Ein Schreibvorgang in ein flüchtiges Feld erfolgt vor jedem nachfolgenden Lesevorgang für dieses Feld.

Read is after write

volatile Stichwort heilt nicht a race condition Situation, in der mehrere Threads schreiben. einige Werte gleichzeitig. Die Antwort lautet synchronized Stichwort [Über]

Infolgedessen ist sie nur dann sicher, wenn eine Gewinde schreibt und andere lesen einfach die volatile Wert

15voto

Niemand hat die Behandlung von Lese- und Schreibvorgängen für lange und doppelte Variablen erwähnt. Lese- und Schreibvorgänge sind atomare Operationen für Referenzvariablen und für die meisten primitiven Variablen, außer für lange und doppelte Variablentypen, die das Schlüsselwort volatile verwenden müssen, um atomare Operationen zu sein. @link

0 Stimmen

Um es noch deutlicher zu machen: Es besteht KEINE NOTWENDIGKEIT, einen Booleschen Wert flüchtig zu machen, da das Lesen und Schreiben eines Booleschen Werts bereits atomar ist.

6 Stimmen

@KaiWang Sie nicht brauchen, um flüchtige auf Boolesche für Atomarität Zwecke verwenden. Aber aus Gründen der Sichtbarkeit kann man das durchaus tun. Ist es das, was Sie sagen wollten?

14voto

ykaganovich Punkte 14234

Ja, volatile muss immer dann verwendet werden, wenn auf eine veränderbare Variable von mehreren Threads zugegriffen werden soll. Dieser Anwendungsfall ist nicht sehr häufig, da in der Regel mehr als eine einzelne atomare Operation durchgeführt werden muss (z. B. Überprüfung des Zustands der Variablen vor ihrer Änderung). In diesem Fall würde man stattdessen einen synchronisierten Block verwenden.

11voto

Aniket Thakur Punkte 62911

Meiner Meinung nach gibt es neben dem Anhalten von Threads zwei weitere wichtige Szenarien, in denen das Schlüsselwort volatile verwendet wird:

  1. Doppelt geprüfter Schließmechanismus . Wird häufig im Singleton-Design Muster. In diesem wird die Singleton-Objekt muss als flüchtig deklariert werden .
  2. Spontane Weckrufe . Es kann vorkommen, dass ein Thread nach einem Wait-Aufruf aufwacht, auch wenn kein Notify-Aufruf erfolgt ist. Dieses Verhalten wird als "spurious wakeup" bezeichnet. Dies kann durch die Verwendung einer bedingten Variable (boolesches Flag) verhindert werden. Legen Sie den wait()-Aufruf in eine while-Schleife, solange das Flag wahr ist. Wenn der Thread also aus einem anderen Grund als Notify/NotifyAll aus dem wait-Aufruf aufwacht, stellt er fest, dass das Flag immer noch wahr ist und ruft daher erneut wait auf. Vor dem Aufruf von notify setzen Sie dieses Flag auf true. In diesem Fall wird der boolesche Flagge wird als flüchtig deklariert .

0 Stimmen

Der gesamte Abschnitt #2 scheint sehr verworren zu sein, da er verlorene Benachrichtigungen, ungewollte Weckvorgänge und Probleme mit der Speichersichtbarkeit miteinander vermengt. Auch wenn alle Verwendungen des Flags synchronisiert sind, ist volatile überflüssig. Ich denke, ich verstehe Ihren Punkt, aber "spurious wakeup" ist nicht der richtige Begriff. Bitte klären Sie das.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X