public class Game{
//why static?
private static Game uniqueGame;
//private so that other class cannot instantiate
private Game(){
}
public static Game getInstance(){
if(uniqueGame == null){
uniqueGame = new Game();
}
return uniqueGame;
}
}
Issue: Thread Problem. When creating two Game Object at the same time, it is possible that we get two objects of Game
Solution: apply the synchronized key word to getInstance(), we force every thread to wait its turn before it can enter the
method. That is, no two threads may enter the method at the same time.--- > Costly since we only care about the issue when first time the Game Object is created
if the other object call getInstance() less frequently then it does not matter
IF not:
Move to an eagerly created instance rather than a lazily created one
/** Using this approach, we rely on the JVM to create the unique instance of the Singleton when
the class is loaded. The JVM guarantees that the instance will be created before any thread
accesses the static uniqueInstance variable. **/
public class Game{
//why static?
private static final Game uniqueGame = new Game();
//private so that other class cannot instantiate
private Game(){
}
public static Game getInstance(){
return uniqueGame;
}
}
这里的instance成员声明成static final, 这意味着
在该类被加载至内存时就创建了实例, 该过程自然是Thread Safe(线程安全)的
Double Check Lock
Volatile KeyWord
The Javavolatilekeyword is used to mark a Java variable as "being stored in main memory". More precisely that means, that every read of a volatile variable will be read from the computer's main memory, and not from the CPU cache, and that every write to a volatile variable will be written to main memory, and not just to the CPU cache.
The Javavolatilekeyword guarantees visibility of changes to variables across threads. This may sound a bit abstract, so let me elaborate.
Further Explanation
/** synchronized only the first time the instance is created **/
public class Game{
//The volatile keyword ensures that multiple threads handle the uniqueInstance variable correctly when it
//is being initialized to the Singleton instance
private volatile static Game uniqueGame;
private Game(){}
public static Game getInstance(){
if(uniqueGame == null){
synchronized (Game.class) {
if (uniqueGame == null) {
uniqueGame = new Game();
}
}
}
return uniqueGame;
}
}
As there are many ways to implement Singleton like using double checked locking or Singleton class with static final
instance initialized during class loading. Former is called lazy loading because Singleton instance is created only when client calls getInstance() method while later is called early loading because Singleton instance is created when class is loaded into memory.
Read more:
http://javarevisited.blogspot.com/2011/03/10-interview-questions-on-singleton.html#ixzz4jGUOnpQ6