最近网上查找资料做了一下总结,Java中的单例模式主要是有以下两种实现方式:
1、public class SingletonClass{
private static final SingletonClass mInstance = new SingletonClass();
public static SingletonClass getInstance(){
return mInstance;
}
private SingletonClass(){
// to do some initialization
}
}
这种方式利用了Java的类加载机制,将单例变量作为类的静态成员变量,在类加载的时候进行初始化,在get方法可以被调用前完成单例的实例化。
2、public class SingletonClass{
private static SingletonClass mInstance;
private SingletonClass(){
// constructor
}
public static synchronized SingletonClass getInstance(){
if(null == mInstance){
mInstance = new SingletonClass();
}
return mInstance;
}
}
这种方式,是典型的单例实现模式(延迟加载方式,只有在需要使用的时候才去创建它)。为了处理好多线程环境下的单例初始化问题,get方法使用了synchronized关键字确保实例化只有一次。虽然这种方式在多线程环境下可能会带来性能问题,因此有人提出了“Double-Check”的解决方案。
3、 public static SingletonClass getInstance(){
if(null == mInstance){
synchronized(SingletonClass.class){
if(null == mInstance)
mInstance = new SingletonClass();
}
}
return mInstance;
}
这种Double Check的方式在JDK 5.0之前是无效的,因为Java的无序内存写入可能会出现一种情况——同步块外面的if (null == instance)可能看到已存在,但不完整的实例。但是JDK 5.0之后,可以通过将mInstance声明为volatile的以避免该问题。
总结:第一种方法可能会造成资源的浪费(不管该实例是否被用到,它总会在类加载时候去实例化),但是它相对于第二种方法会有执行速度上的优势。所以在日常开发中应根据具体情况使用1或者3的方法。