I was doing some research about singletons, specifically regarding lazy vs eager initialization of singletons.
An example of eager initialization:
public
In my opinion, this is an inappropriate pattern to use. It makes assumptions about the JVM's behavior which are non-trivial and confusing. Also, it has a dummy class. Dummy classes should be avoided when possible.
I suggest the straightforward approach:
public class Foo {
private volatile static final Foo instance = null;
private Foo() {
}
public static Foo instance() {
if (instance == null) instance = new Foo();
return instance;
}
}
}
... although, this does not work as-is - it's not thread safe.. What you really want is the double-check pattern presented in Item 71 of Bloch's Effective Java; see here. Adapting the example at the link to your case, we get:
public class Foo {
private volatile static final Foo instance = null;
private Foo() {
}
public static Foo instance() {
if (instance != null) return instance;
synchronized(instance) {
Foo result = instance;
if (instance == null) {
result = instance = new Foo();
return result;
}
}
}
Notes:
You first design is actually lazy. Think about it, the instance is only created when the class is initialized; the class is only initialized when the getSingleton()
method is called [1]. So the instance is only created when it's asked for, i.e. it's lazily created.
[1] http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1
Your second code snippet is, in my opinion, the best way of thread-safe lazily initializing a singleton. It actually has a pattern name
Initialization-on-demand holder idiom
I would suggest you use it.
The best way is actually to use the Enum Way:
public enum Singleton {
INSTANCE;
public void execute (String arg) {
//... perform operation here ...
}
}
The second one is very bad in terms of readability, first one is suitable. Have a look at this article. Its about double check locking, but also will give you wide information about singletons multithreading.