class T {
    int m = 8;
}
T t = new T();
Copy the code
0 new #2 <T>
3 dup
4 invokespecial #3 <T.<init>>
7 astore_1
8 return
Copy the code

First, a new object is allocated a memory space, m = 0; And then execute the constructor, so m = 8;

Because thread1 is semi-initialized at creation time, it is possible to rearrange instructions, and thread2 uses semi-initialized T instead of null, thus requiring volatile.