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();
}
}
I wrote the code as above.
The result I expected was:
running! (many times)
cleanup!
but when I ran it I got:
running! (many times)
and it didn't stop.
So, I added System.out.println(running);
to the while statement.
It was printed as expected.
Wonder why this is happening. Curious how to fix it.
It keeps running because there is nothing to tell the started thread that the main thread changed the variable. The change by the main thread isn’t visible to the other thread.
The reason it works when you add println because both threads are using and synchronizing on the console print writer, introducing a happens-before relationship that makes the variable update visible.
You can make the running variable volatile and that will make the change visible without the println.