Heim  >  Artikel  >  Java  >  Flüchtiges Schlüsselwort in Java

Flüchtiges Schlüsselwort in Java

王林
王林Original
2024-08-30 16:19:44583Durchsuche

Volatile funktioniert in Java so: Wenn wir möchten, dass mehrere Threads gleichzeitig auf unser Objekt zugreifen, können wir dieses Schlüsselwort verwenden. Dieses Schlüsselwort ist eine weitere Möglichkeit, unsere Klasse, unseren Code und unsere Methode threadsicher zu machen, was bedeutet, dass mehrere Threads problemlos auf dieselbe Ressource zugreifen können. Wir meinen, dass ein Verstoß gegen das Schlüsselwort bedeutet, dass wir sagen können, dass mehrere Threads diesen Variablenwert gleichzeitig bearbeiten.

Starten Sie Ihren kostenlosen Softwareentwicklungskurs

Webentwicklung, Programmiersprachen, Softwaretests und andere

Wenn wir das Schlüsselwort volatile in Java verwenden?

Wenn Sie Ihren Code threadsicher machen möchten, können Sie sich für das Schlüsselwort „Verletzt“ entscheiden. Außerdem bietet es Synchronisierung; In diesem Fall ist es eine gute Wahl.

Jede Variable, die wir mit diesem Schlüsselwort deklarieren, wird nicht im Cache gespeichert; Alle von uns ausgeführten Vorgänge, wie Lesen und Schreiben, werden im Hauptspeicher abgelegt.

class DemoSharedObject
{
static int sharedresources = 10;
}

Unten ein Fall, der zu Dateninkonsistenzen führt:

Wir haben eine Klasse namens DemoSharedObject. Nehmen wir an, dass mehrere Threads an dieser Klasse arbeiten und den Wert der Klassenmitglieder ändern werden. Wenn also mehrere Threads auf den verschiedenen Prozessoren laufen, verfügt jeder dieser Threads über seine eigenen lokalen Kopierressourcen. Wenn also ein Thread den Wert gemeinsamer Ressourcen ändern würde, würde sich dieser Wert nicht sehr schnell im Hauptspeicher widerspiegeln. In diesem Fall wissen unsere anderen Threads jedoch nichts über den aktuellen Wert der gemeinsam genutzten Ressourcen, sodass dies zu einem Problem mit der Dateninkonsistenz führt.

In Java gibt es zwei Dinge: Synchronisationsanweisungen und Synchronisationsmethoden.

Synchronisationsmethode

In diesem Fall fügen wir einfach das synchronisierte Schlüsselwort zur Methodensignatur hinzu.

Syntax:

public synchronized return_type method_name(){}

Beispiel:

public class Demosynchronized {
private int c = 0;
public synchronized void method1() {
c++;
}
public synchronized void method2() {
c--;
}
public synchronized int method3() {
return c;
}
}

Im obigen Beispiel erhöhen und verringern wir lediglich den Zähler, aber wir müssen ein synchronisiertes Schlüsselwort mit der Methode einführen, damit keine Dateninkonsistenz auftritt und alle Threads den aktualisierten Wert erhalten.

Wenn also der erste Thread seine Verarbeitung mit method1() ausführt, werden alle anderen Threads blockiert (suspendiert); Kein anderer Thread kann auf dasselbe Objekt zugreifen, bis der Arbeitsthread bereits die Sperre des Objekts erhalten hat. So vermeiden sie Inkonsistenzen der Daten.

Außerdem gibt es jetzt eine weitere Funktion: Immer wenn der Thread seine Operation an method1() abschließt, d auch zu anderen Threads.

Synchronisierte Anweisung

Syntax:

synchronized(){}

Beispiel:

public void demo(String namestr) {
synchronized(this) {
lastName = namestr;
count++;
}
list.add(namestr);
}

Im obigen Beispiel haben wir einen synchronisierten Block, der die Daten für uns verwaltet. So wird namestr durch die demo()-Methode synchronisiert. Das bedeutet die Daten, die wir synchronisieren möchten; Wir müssen sie nur in diesem Block platzieren.

Wenn wir also zwei Threads haben, die auf dasselbe Objekt schreiben und lesen, was bedeutet, dass wir mehrere Threads haben, die zu Lese- und Schreibzwecken auf dasselbe Objekt zugreifen, sollten wir uns für das Schlüsselwort „Verletzt“ entscheiden, da es uns nicht das liefert Garantie für das Blockieren von Threads, es sei denn und bis andere Threads ihre Ausführung stoppen. In diesem Fall sollten wir uns also für die Synchronisierung entscheiden, da sie uns einige weitere Funktionen über das Verletzungsschlüsselwort wie :

bietet

Es kann sowohl mit der Methode als auch mit dem Anweisungsblock verwendet werden, was bedeutet, dass wir nicht die gesamte Methode synchronisieren müssen; Wir können unseren Code auch in den Block schreiben, den wir synchronisieren möchten.

Wenn wir den Wert der flüchtigen Variablen lesen oder schreiben, lesen oder schreiben sie den Wert direkt in den Hauptspeicher, was keine gute Praxis ist und im Vergleich zum Cache auch teuer ist. Denken Sie also nach, bevor Sie flüchtige Schlüsselwörter verwenden. es wird sich direkt auf Ihre Leistung auswirken.

Angenommen, wir haben mehrere Threads, die nicht von der Antwort des anderen abhängig sind, was bedeutet, dass Lesen und Schreiben unabhängig voneinander sind, um in diesem Fall die flüchtigen Schlüsselwörter zu verwenden. Aber wir haben noch einen weiteren Fall, in dem es nicht geeignet ist, das unten erläuterte Schlüsselwort volatile zu verwenden:

Suppose thread has generated the first value of the volatile variable, and this current value will be used further to generate the new volatile variable values; in this case, this volatile keyword is not a good fit to generate the correct result; this condition will lead to a race condition were all thread going to read the same value but generate the new value for them and write the value to main memory and override each other values, so this will leads to the wrong result, or we can say data inconsistency issue, so here volatile keyword is not good enough to avoid this case we have to move to synchronization where we have to types to make our code synchronized, i.e. synchronized method and synchronized statement.

Example

Code:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TvvApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(TvvApplication.class);
private static final Object aclock = new Object();
private static final Object aclock1 = new Object();
private static volatile int MY_INT = 0;
public static void main(String[] args) {
System.out.println("without block");
System.out.println("with block calling static method :: ");
testBlock();
}
static void testBlock1() {
synchronized (aclock1) {
MY_INT = MY_INT + 1;
System.out.println( Thread.currentThread().getName() +"new lock we create and printing voilatile value using block for block one:: "+ MY_INT);
}
}
static void testBlock() {
synchronized (aclock) {
MY_INT = MY_INT + 1;
System.out.println( Thread.currentThread().getName() +"new lock we create and printing voilatile value using block for block two:: "+ MY_INT);
}
}
}

Output :

<img src="https://img.php.cn/upload/article/000/000/000/172500598784733.png" alt="Flüchtiges Schlüsselwort in Java" >

Conclusion

So this can provide thread safety when data does not depend on each other; if data depends, we should go for synchronization.

Das obige ist der detaillierte Inhalt vonFlüchtiges Schlüsselwort in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:AWT-Komponenten in JavaNächster Artikel:AWT-Komponenten in Java