[FIXED] Java-Variablenänderung wurde während der synchronen Verarbeitung nicht übernommen

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)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like