Singleton Pattern in Multi threaded environment
Your first example is absolutely correct, and is usually the preferred "idiom" for singletons. The other one is to make a single-element enum:
public enum Single {
INSTANCE;
...
}
The two approaches are pretty similar unless the class is Serializable, in which case the enum approach is much easier to get right -- but if the class isn't Serializable, I actually prefer your approach the enum one, as a stylistic matter. Watch out for "accidentally" becoming Serializable due to implementing an interface or extending a class which is itself Serializable.
You are also right about the second check for nullity in the double-checked lock example. However, the sing
field must be volatile
for this to work in Java; otherwise, there is no formal "happens-before" edge between one thread writing to sing
and another thread reading to it. This can result in that second thread seeing null
even though the first thread assigned to the variable, or, if the sing
instance has state, it could even result in that second thread seeing only some of that state (seeing a partially-constructed object).
1) Class #1 is good for multithreaded environment
2) Class #2 is a singleton with lazy initialization and double checked locking, it's a known pattern and it needs to use synchronization. But your implementation is broken, it needs volatile
on the field. You can find out why in this article http://www.javaworld.com/article/2074979/java-concurrency/double-checked-locking--clever--but-broken.html
3) a Singleton with one method does not need to use lazy pattern, because its class will be loaded and initialized only at first usage.