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.