Ausgabe
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test extends Thread {
private boolean running;
private Lock cleanupLock;
@Override
public void run() {
cleanupLock.lock();
while (running) {
System.out.println("running!");
}
cleanupLock.unlock();
}
private void cleanup() {
running = false;
cleanupLock.lock(); //wait for thread
System.out.println("cleanup!");
}
public Test() {
running = true;
cleanupLock = new ReentrantLock();
this.start();
cleanup();
}
public static void main(String argv[]) {
new Test();
}
}
Ich habe den Code wie oben geschrieben.
Das Ergebnis, das ich erwartet hatte, war:
laufend! (viele Male)
Aufräumen!
aber als ich es laufen ließ, bekam ich:
laufend! (viele Male)
und es hörte nicht auf.
Also habe ich System.out.println(running);
die while-Anweisung hinzugefügt.
Es wurde wie erwartet gedruckt.
Frage mich, warum das passiert. Neugierig, wie man es repariert.
Lösung
Es läuft weiter, weil nichts dem gestarteten Thread mitteilt, dass der Haupt-Thread die Variable geändert hat. Die Änderung durch den Hauptthread ist für den anderen Thread nicht sichtbar.
Der Grund, warum es funktioniert, wenn Sie println hinzufügen, liegt darin, dass beide Threads den Druckschreiber der Konsole verwenden und synchronisieren, wodurch eine Happening-Before-Beziehung eingeführt wird, die die Variablenaktualisierung sichtbar macht.
Sie können die laufende Variable flüchtig machen, wodurch die Änderung ohne println sichtbar wird.
Beantwortet von – Nathan Hughes
Antwort geprüft von – Mildred Charles (FixError Admin)