单例模式:整个应用中保证只有一个类的实例存在。比如打印缓冲池和文件系统等。
于是我们很容易想到可以把类的构造函数写成私有的,然后提供方法可以返回一个静态的实例。
写法一:
1 package designPattern; 2 3 public class SingletonClass 4 { 5 private static final SingletonClass instance = new SingletonClass(); 6 7 public static SingletonClass getInstance() 8 { 9 return instance; 10 } 11 12 private SingletonClass() 13 { 14 15 } 16 }
评价:只要加载这个类,即使没有使用过,实例也会被创建。(这个缺点其实挺勉强的,既然创建了这个类为什么不使用呢?)
写法二:
1 package designPattern; 2 3 public class SingletonClass 4 { 5 private static SingletonClass instance = null; 6 7 public synchronized static SingletonClass getInstance() 8 { 9 if(instance == null) 10 { 11 instance = new SingletonClass(); 12 } 13 return instance; 14 } 15 16 private SingletonClass() 17 { 18 19 } 20 }
评价:调用的时候再创建实例,但由于步骤的分离,为了线程安全需要加上同步化的关键字,同步化会让程序效率变低。
写法三:
1 package designPattern; 2 3 public class SingletonClass 4 { 5 private volatile static SingletonClass instance = null; 6 7 public static SingletonClass getInstance() 8 { 9 if(instance == null) 10 { 11 synchronized(SingletonClass.class) 12 { 13 if(instance == null) 14 { 15 instance = new SingletonClass(); 16 } 17 } 18 } 19 return instance; 20 } 21 22 private SingletonClass() 23 { 24 25 } 26 }
评价:在写法二的基础上,只有instance == null的时候才加锁,所以提高了效率,但是感觉代码略显冗余。
写法四:
1 package designPattern; 2 3 public class SingletonClass 4 { 5 private static class SingletonClassInstance 6 { 7 private static final SingletonClass instance = new SingletonClass(); 8 } 9 10 public static SingletonClass getInstance() 11 { 12 return SingletonClassInstance.instance; 13 } 14 15 private SingletonClass() 16 { 17 18 } 19 }
评价:在类的内部多实现了一个静态类,只在调用的时候才会创建实例,且不需要同步化,比较推荐使用。