If I understand the program order rule (each action in a thread
happens-before every action in that thread that comes later in the
program order)
No it doesn't.
Here you don't have one thread but two threads :
the main thread and the thread created and started by the main thread :
Thread t = new Thread() {...};
t.start();
And living threads of the JVM are by design concurrent.
If the two statements had been executed in the same thread, it would
be safe to assume that the value printed out would be "1". But if the
two statements are executed in separate threads, the value printed out
might well be "0", because there's no guarantee that thread A's change
to counter will be visible to thread B — unless the programmer has
established a happens-before relationship between these two
statements.
The happens-before relationship occurs only if all statements are performed by the same thread or if you explicitly create the happens-before relationship.
Extract from the Memory Consistency Errors tutorial :
There are several actions that create happens-before relationships.
One of them is synchronization, as we will see in the following
sections.
As said above, the statements are performed by two threads.
And you don't explicitly synchronize statements.
So you have a race condition between the threads and as a general rule, the execution order should be considered as unpredictable.
Now in practice, for a such short statement : x = y + 1
:
t.start();
x = y + 1;
The assignment of the adding operation is so short to be executed as it is very likely to occur before that the thread referenced by t
be effectively run.
Besides, modern CPUs have multiple cores.
So if the CPU has thread availability, the main thread will not be paused to make the new thread running.
The two threads will so be executed at the "same time".
But as x = y + 1;
is much faster to be executed as starting and running a thread, the first statement can only finish before the second one.