Consider the following example:

public class Example {
    public int a, b, c, d;
    
    public void doIt() {
       a = b + 1;
       c = d + 1;
    }
}

If this class is used is a single-threaded application, then the observable behavior will be exactly as you would expect. For instance:

public class SingleThreaded {
    public static void main(String[] args) {
        Example eg = new Example();
        System.out.println(eg.a + ", " + eg.c);
        eg.doIt();
        System.out.println(eg.a + ", " + eg.c);
    }
}

will output:

0, 0
1, 1

As far as the “main” thread can tell, the statements in the main() method and the doIt() method will be executed in the order that they are written in the source code. This is a clear requirement of the Java Language Specification (JLS).

Now consider the same class used in a multi-threaded application.

public class MultiThreaded {
    public static void main(String[] args) {
        final Example eg = new Example();
        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    eg.doIt();
                }
            }
        }).start();
        while (true) {
            System.out.println(eg.a + ", " + eg.c);
        }
    }
}

What will this print?

In fact, according to the JLS it is not possible to predict that this will print:

1 - In practice the presence of the println statements is liable to cause some serendipitous synchronization and memory cache flushing. That is likely to hide some of the effects that would cause the above behavior.

So how can we explain these?

Reordering of assignments

One possible explanation for unexpected results is that the JIT compiler has changed the order of the assignments in the doIt() method. The JLS requires that statements appear to execute in order from the perspective of the current thread. In this case, nothing in the code of the doIt() method can observe the effect of a (hypothetical) reordering of those two statement. This means that the JIT compiler would be permitted to do that.

Why would it do that?