Singleton: Ensure a class only has one instance and provide a global point of access to it.
code implementation
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance==null)
uniqueInstance=new Singleton();
return uniqueInstance;
}
}
We have a problem
The new Singleton code was running fine. The only thing we can think of is that we just added some optimizations to the Controller that makes use of multiple threads.
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (uniqueInstance ==null)
uniqueInstance=new Singleton();
return uniqueInstance;
}
}
I agree this fixes the problem. but synchronization is expensive.
it's actually a little worse than you make out; the only time synchronization is relevant is the first time through this method.
Can we improve multithreading?
1. Do nothing if the performance of getInstance() isnt critical to your application.
If calling the getInstance() method isnt causing substantial overhead for your application. forget about it. Keep in mind that synchronizing a method can decrease performance by a factor of 100, so if a high traffic part of your code begins using getInstance(), you may have to reconsider.
2 move to an eagerly created instance rather than a lazily created one.
if your application always creates and uses an instance of the Singleton or the overhead of creation and runtime aspects of Singleton are not oncrous, you may want to create your singleton eagerly.
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return uniqueInstance;
}
}
Using this approach, we rely on the JVM to create the unique instance of the Singleton when the classs is loaded. The JVM guarantees that the instance will be created before any thread access the static uniqueInstance variable.
3 Use "double-checked locking" to reduce the use of synchronization in getInstance()
With double-checked locking, we first check to see if an instance is created, and if not, then we synchronize. This way, we only synchronize the first time through, just what we want.
Let's check out the code:
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance==null) {
synchronized (Singleton.class) {
if (uniqueInstance==null)
uniqueInstance=new Singleton();
}
}
return uniqueInstance;
}
}