Why won't this 'if' statement run in a while loop without something else also happening in the while loop?

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.

Jon Skeet
people
quotationmark

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.)

people

See more on this question at Stackoverflow