Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite loop problem with while loop and threading [duplicate]

Using a basic example to illustrate my problem I have 2 near-identical bits of code.

This code causes the while loop to run infinitely.

private boolean loadAsset() {
    new Thread(new Runnable() {

        @Override
        public void run() {

            // Do something
            loaded = true;

        }
    }).start();

    while (!loaded) {
        // System.out.println("Not Loaded");
    }
    System.out.println("Loaded");
    return false;
}

This code however (i.e. doing something in the while loop) causes the loaded variable to be successfully evaluated and allows the while loop to break and method to finish.

private boolean loadAsset() {
    new Thread(new Runnable() {

        @Override
        public void run() {

            // Do something
            loaded = true;

        }
    }).start();

    while (!loaded) {
        System.out.println("Not Loaded");
    }
    System.out.println("Loaded");
    return false;
}

Can anyone explain to me why this is?

like image 644
Sonoman Avatar asked Jul 12 '11 13:07

Sonoman


3 Answers

The first loop only "appears" to run infinitely. You're actually running an "active wait", burning 100% of your CPU, such that your OS or JVM can't make a context switch and let the other thread run.

With the System.out.println() on the other hand, there is I/O involved, resulting in a somewhat "inactive wait". The OS or JVM can switch contexts and the other thread starts.

If you'd run your first program for 10 hours, I'm sure the loop would break eventually

like image 171
Lukas Eder Avatar answered Nov 02 '22 12:11

Lukas Eder


Check that 'loaded' is definitely declared as volatile.

Explanation: if a variable is read and/or written by multiple threads, then you need to take appropriate thread-safety measures. One such thread-safety measure is volatile, which is suitable for primitive values (or object references) which are read or written as 'simple' actions with the value written on a given occasion not depending on the previously read value. For more information, I have an article about volatile on my web site (along with other information about thread-safety generally) that may be of help.

like image 22
Neil Coffey Avatar answered Nov 02 '22 11:11

Neil Coffey


If loaded is not volatile, the JIT is free to optimise it by placing it in a register and not loading it from memory every time. In the second case, the loop is too complex for the JIT to assume it doesn't need to load loaded each time.

Note: its is the JIT not the javac compiler which optimises the code.

like image 4
Peter Lawrey Avatar answered Nov 02 '22 12:11

Peter Lawrey