Wenn der Zugriff auf gemeinsam genutzte veränderliche Daten nicht synchronisiert werden kann, können die Folgen verheerend sein, selbst wenn die Variable atomar lesbar und beschreibbar ist.
Betrachten wir ein Thread-Synchronisierungsproblem. Für die Thread-Synchronisierung stellt die Java-Klassenbibliothek die Methode Thread.stop bereit. Diese Methode lohnt sich jedoch nicht, da sie von Natur aus unsicher ist. Es wäre besser, Polling zu verwenden, wie zum Beispiel das folgende Programm.
Kopieren Sie den Codecode wie folgt:
import java.util.concurrent.TimeUnit;
öffentliche Klasse StopThread {
/**
* @param args
*/
privater statischer boolescher Wert stopRequested;
public static void main(String[] args)
wirft InterruptedException{
Thread-HintergrundThread = neuer Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(!stopRequested){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
Sie denken vielleicht, dass der Hauptthread stopRequested auf true setzt, nachdem dieses Programm etwa eine Sekunde lang ausgeführt wurde, was dazu führt, dass der neue Thread im Hintergrund stoppt. Dies ist jedoch nicht der Fall, da der Hintergrundthread die Änderung darin nicht sehen kann Wert, sodass die Schleife endlos weiterläuft. Dies ist die Folge der nicht synchronisierten Daten. Machen wir das also synchron.
Kopieren Sie den Codecode wie folgt:
import java.util.concurrent.TimeUnit;
öffentliche Klasse StopThread {
/**
* @param args
*/
privater statischer boolescher Wert stopRequested;
private statische synchronisierte void requestStop(){
stopRequested = true;
}
privater statischer synchronisierter boolescher Wert stopRequested(){
return stopRequested;
}
public static void main(String[] args)
wirft InterruptedException{
Thread-HintergrundThread = neuer Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(!stopRequested()){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
Dadurch wird eine Datensynchronisierung erreicht. Es ist zu beachten, dass sowohl die Schreibmethode (requestStop) als auch die Lesemethode (stopRequested) synchronisiert werden müssen, da sie sonst immer noch nicht im eigentlichen Sinne synchronisiert sind.
Darüber hinaus können wir den flüchtigen Variablenmodifikator verwenden, um Synchronisierungsaufgaben einfacher abzuschließen.
Kopieren Sie den Codecode wie folgt:
import java.util.concurrent.TimeUnit;
öffentliche Klasse StopThread {
/**
* @param args
*/
privater statischer flüchtiger boolescher Wert stopRequested;
public static void main(String[] args)
wirft InterruptedException{
Thread-HintergrundThread = neuer Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(!stopRequested){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}