So, the other day I made a fractal drawing program, and when it got too slow, I thought I would make it a bit faster by multithreading it. So I introduced a couple of threads to each draw a portion of the image. To know when I was done with the threads, I introduced two variables, AMOUNT_OF_THREADS and threadsDone. I created AMOUNT_OF_THREADS threads, that each drew their own partition and increased threadsDone when done. In the main method, I put in
while (threadsDone < AMOUNT_OF_THREADS)
    ;
It surprised me that that loop never finished looping. I knew it because each thread printed out "Thread done" and when the main method loop was done it should have printed out "Main done" but it didn't. I tried to print out threadsDone < AMOUNT_OF_THREADS and now the loop stopped. Weird.
I did some further testing and this problem seems only to occur if the thread takes >2ms to run or the loop takes >2ms each time it loops. Sometimes this bug occurs when the thread takes 2ms to run.
I suspect that the print function made the loop take >2ms to run and that made it work when I printed out the value, but I still wonder why this happens.
So my question is, why does this happen? Is it a bug in the compiler/JVM, or anything else? I asked my dad, and he replied after thinking for a few minutes that it has to be the while loop running too fast, but he wasn't sure.
Here's a little example of some code that has this problem:
public class WhileThread {
    public static boolean threadDone = false;
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                threadDone = true;
                System.out.println("Thread done.");
            }
        }).start();
        while (!threadDone) {
        }
        System.out.println("Main program done.");
    }
}
When you change the 0 in the Thread.sleep into a 10, this bug never happens.
If it matters, I use a Macbook Air with Java SE 8.
 
     
    