The code below (Java Concurrency in Practice listing 16.3) is not thread safe for obvious reasons:
public class UnsafeLazyInitialization {
private static
Nothing sets the reference to null once it is non-null. It's possible for a thread to see null after another thread has set it to non-null but I don't see how the reverse is possible.
I'm not sure instruction re-ordering is a factor here, but interleaving of instructions by two threads is. The if branch can't somehow be reordered to execute before its condition has been evaluated.