在多线程环境中,单例模式可能会创建多个实例,如果使用synchronized关键字来修饰getInstance方法,又造成访问该方法的性能变慢。
如何解决这个问题?
1. 采用急切实例化,直接把属性实例化。
private static Singleton uniqueInstance = new Singleton();
2. 使用“双重加锁”判断是否已实例化
/**
* 线程安全的单例类, 使用”双重检查加锁“,在getInstance()中减少使用同步。 这种方法不适用于JDK1.4及之前的版本
* Created by jiangzhiqiang on 15/2/5.
*/
public class Singleton {
// volatile关键字确保:当uniqueInstance变量被初始化成Singleton实例时,多个线程能正确地处理uniqueInstance变量
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;
}
}
3. 另一种实现方式,使用静态内部类实现单例:
public class Singleton {
/**
* 类级的内部类,该内部类的实例与外部类的实例没有绑定关系, 而且只有被调用到才会装载,从而实现了延迟加载
*/
private static class SingletonHolder {
/**
* 静态初始化器,由JVM来保证线程安全
*/
private static Singleton instance = new Singleton();
}
/**
* 私有化构造方法
*/
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}