I'm having a problem where an if statement is only running if there is something else happening before it in the while loop.
Here is the code I want to use:
public void load() throws IOException, InterruptedException {
while (true) {
if (findGame == true) {
System.out.println(findGame);
}
}
}
That is simplified but it shows my problem. Basically, when findGame == true
, the if statement does not run. The reason I don't think the if statement is running is because the variable is not being printed out to the console.
I did some tests and found that the if statement ran with the following code:
public void load() throws IOException, InterruptedException {
while (true) {
System.out.println("foo"); // New code added
if (findGame == true) {
System.out.println(findGame);
}
}
}
My question is why does it work with the above code but not the first one? The only difference between the two is that the one that works has something else added to the while loop.
If it makes a difference, the code I've shown above is running in a separate thread.
If it makes a difference, the code I've shown above is running in a separate thread.
And that's the problem. You're relying on a value set by one thread to be visible in another - and there's no such guarantee without memory barriers being involved. In your second code, the call to println
is almost certainly responsible for creating the memory barriers required for the reading thread to "see" the value written by the writing thread. Memory models are hard, unfortunately :(
If you use AtomicBoolean
instead of just a boolean
field, you may well find the first code works instead - but even so, a tight loop is generally a bad idea. It would be better to use a semaphore or some similar kind of signalling, so the "reading" thread could just wait (idly) until there's a change. Look into java.util.concurrent
for classes such as Semaphore
and CountDownLatch
. (You can do it with just wait
and notify
, but it'll be simpler if you use higher-level abstractions.)
See more on this question at Stackoverflow