Eager instantiation does not require explicit synchronisation for sharing the reference of the field because the JVM will have handled it for us already as part of the class loading mechanism.
To elaborate in more detail, before a class becomes available to any thread for use, it will have been loaded, verified and initialised. The compiler rewrites the static field assignment into this initialisation stage and via the rules of the Java Memory Model and the underlying hardware architecture will ensure that all threads who access that class will see this version of the class. This means that the JVM will have handled any hardware barriers etc for us.
That said, I would recommend marking the eager initialisation final. This will make your intent clearer and the compiler will enforce that the eager initialisation never changes. If it did, then concurrency control would be required again.
private static **final** Singleton INSTANCE = new Singleton();
FYI If you are interested, section 5.5 of the Java Virtual Machine Specification covers this in much more detail. A couple of choice snippets from the spec are
*"Because the Java Virtual Machine is multithreaded, initialization of a class or interface requires careful synchronization"* *"For each class or interface C, there is a unique initialization lock LC"* *9&10) "Next, execute the class or interface initialization method of C" "If the execution of the class or interface initialization method completes normally, then acquire LC, label the Class object for C as fully initialized, notify all waiting threads, release LC, and complete this procedure normally."*
It is in step 10 of the spec where the static fields will have been set, and the use of a lock (LC) is used to ensure that only one thread performs the initialisation and that the result is shared correctly.
;).