Endless loop problem with while loop and threading

Using a basic example to illustrate my problem, I have two almost identical bits of code.

This code makes the while run indefinitely.

 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; } 

However, this code (i.e. does something in the while loop) causes a successful evaluation of the loaded variable and allows you to interrupt the while and complete the method.

 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 someone explain to me why this is?

+4
source share
5 answers

Make sure that "loaded" is specifically declared as volatile.

Explanation: if a variable is read and / or written by multiple threads, then you need to take appropriate security measures . One such thread safety measure is volatile, which is suitable for primitive values ​​(or object references) that are read or written as "simple" actions with a value written in this case independent of the previously read value. For more information, I have an article on volatile on my website (along with other thread safety information in general), which may be of help.

+6
source

The first cycle only "appears" to start endlessly. In fact, you start "active waiting", burning 100% of your processor so that your OS or JVM cannot create a context switch and allow another thread to start.

With System.out.println() , on the other hand, I / O is involved, which leads to a somewhat "inactive wait". The OS or JVM can switch contexts and start another thread.

If you run your first program in 10 hours, I'm sure the loop will eventually break

+6
source

If loaded not volatile, the JIT can optimize it by putting it in a register and not loading it from memory every time. In the second case, the loop is too complicated for JIT to suggest that there is no need to load loaded every time.

Note: this JIT is not a javac compiler that optimizes code.

+4
source

Read Memory Negotiation Errors . Basically, different threads have inconsistent ideas about which data should be the same. To resolve this issue, read Sync . Or simply declare loaded as volatile , as its value is written only by one stream.

+2
source

I believe that you are experiencing Busy Wait with an empty loop that will never sleep. Thus, your thread to set loaded to true never starts.

0
source

All Articles