说明:本文主要是作为读书笔记(Head First 设计模式),代码也来自于该书。
我一直以为我可以很快地写出一个单件模式的代码来,也正如书中列的代码:
1 public class Singleton{ 2 private static Singleton uniqueInstance; 3 private Singleton(){} 4 public static Singleton getInstance(){ 5 if(uniqueInstance==null) 6 { 7 uniqueInstance=new Singleton(); 8 } 9 return uniqueInstance; 10 } 11 }
这段代码在多线程的情况下就会出问题。如果有两个线程A、B,A先执行到line 5,接着B执行line 5,再切换到A执行line 7,然后切换到7执行line 7,则线程A、B会分别得到一个不同的对象,就违法了单例模式的定义了。
书中给出了三个解决方法:
1. getInstance方法声明为synchronized。显然,这种做法会严重影响性能。
2. 使用"急切"创建实例,而不用延迟实例化的做法。当应用程序实际上不需要创建单件实例时,该方法就会造成浪费。
1 public class Singleton{ 2 private static Singleton uniqueInstance=new Singleton(); 3 private Singleton(){} 4 public static Singleton getInstance(){ 5 return uniqueInstance; 6 } 7 }
3. 用"双重检查加锁"。
1 public class Singleton{ 2 private static volatile Singleton uniqueInstance; 3 private Singleton(){} 4 public static Singleton getInstance(){ 5 if(uniqueInstance==null) 6 { 7 synchronized(Singleton.class) 8 { 9 if(uniqueInstance==null) 10 { 11 uniqueInstance=new Singleton(); 12 } 13 } 14 } 15 return uniqueInstance; 16 } 17 }
相比而言,方法3是较好的实现方法。