I ran into some problems with a multi-threaded Java-program and distilled it down to a very simple example - still my puzzlement isn't less!
The example program it shown below. So what does this do (or was intended to do)?. Well, the main() function starts off a simple thread, based on a static, inner class Runnable. This Runnable contains two nested loops, that does a simple calculation on a local variable "z" for a total of 10^12 iterations (10^6 * 10^6), after which it will print out the result and exit. After spawning this worker thread, the main thread goes into a loop of its own where it prints the string "Z" to the console after which it sleeps (using Thread.sleep()) for 1 second, then repeats this over and over.
So running this program, I would expect it to print out "Z" every 1 second while the calculating thread was doing its job.
However, in fact what happens is that the calculating thread is started, and the main thread displays the first "Z" but then nothing happens. It appears to hang in the Thread.sleep call, either infinitely or at least much, much longer than the requested 1000 ms.
Note that this is on a fast, quad-core machine with multi-threading, so there should be no trouble in running the threads simultaneously. The other cores appear as idle in Windows task manager. Also, even on a single-core system I would expect the operating system to periodically preempt the calculating thread, in order to allow the main-thread to print the strings. Further, there's no shared variables or lock between the threads, so they shouldn't be able to block each other.
Even more strangely, it appears to be critical for the behavior, that there are two nested loops in the Runnable. With just one loop, with the same number of iterations, everything works as expected.
I've tested this on Windows 10 64-bit with Java 1.8.0_73.
Can someone explain this behavior?
public class Calculate {
static class Calc implements Runnable
{
@Override
public void run() {
int z = 1;
for(int i = 0; i < 1000000; i++) {
for(int j = 0; j < 1000000; j++) {
z = 3*z + 1;
}
}
System.out.println("Result: " + z);
}
}
public static void main(String[] args) throws Exception
{
Thread t = new Thread(new Calc());
t.start();
while(true) {
System.out.println("Z");
Thread.sleep(1000);
}
}
}
Update 1: It has been suggested that this might be a duplicate of Busy loop in other thread delays EDT processing. Many symptoms in my case are the same, but it is hard to tell if they truly are the same cause, because the other problem doesn't appear to have been fully diagnosed. But it is a likely possibility.
Update 2: I have filed a bug report with Oracle. I will post link if it is accepted and I find it.
Update 3: Accepted as bug in Java 8 and 9: https://bugs.openjdk.java.net/browse/JDK-8152267