Question
The following while loop is not checking if "stopping" is true:
while (jobs.isEmpty()) {
if (stopping) {
running = false;
break;
}
}
however, if I insert any other statement before the if-statement, the if statement is checking reliably, like in the following loop:
while (jobs.isEmpty()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (stopping) {
running = false;
break;
}
}
of course, i want it to work without the 1 sec delay, any ideas how to fix that, or why it is not working in the first place?
Clarification
To clarify it, i created a simple Test Class:
public class Test {
static boolean stopping = false;
static boolean running = true;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
while (true) {
if (stopping) {
running = false;
break;
}
}
System.out.println("1. Worked");
}).start();
new Thread(() -> {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (stopping) {
running = false;
break;
}
}
System.out.println("2. Worked");
}).start();
Thread.sleep(1000);
stopping = true;
Thread.sleep(5000);
System.exit(0);
}
}
Output:
2. Worked
Process finished with exit code 0
stoppingfrom one thread are visible in another. In general, tight loops like this are a bad idea - it's better to signal from one thread to another - there are lots of options here, depending on what the real use case is. The simplest fix at the moment is probably to useAtomicBoolean. (Makingstoppingvolatile might work, but I don't remember enough details about the Java memory model to say for sure.)volatileuntil you've read about and thoroughly absorbed everything in the (long and complicated) Java Memory Model documentation.