单例模式

1、单例模式定义

在整个应用中,同一时刻,有且只能有一种状态的类可以考虑写成单例模式;

2、单例模式的好处

节约内存空间,减少无谓的GC消耗;

3、单例模式示例代码

3.1 标准的单例模式- 这种是在不考虑并发的情况下的代码,所以不是很严谨;

public class Singleton {

    //一个静态的实例
    private static Singleton singleton;
    //私有化构造函数
    private Singleton(){}
    //给出一个公共的静态方法返回一个单一实例
    public static Singleton getInstance(){
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

3.2 为防止并发的情况实例化多个破坏单例模式,以下代码加了同步锁来避免这种情况;

public class SynchronizedSingleton {

    //一个静态的实例
    private static SynchronizedSingleton synchronizedSingleton;
    //私有化构造函数
    private SynchronizedSingleton(){}
    //给出一个公共的静态方法返回一个单一实例
    public synchronized static SynchronizedSingleton getInstance(){
        if (synchronizedSingleton == null) {
            synchronizedSingleton = new SynchronizedSingleton();
        }
        return synchronizedSingleton;
    }
    
}

3.3 上面3.2的这种在方法上加同步锁的做法可以避免产生多个实例的问题,在一个线程访问这个方法时,其它所有的线程都要处于挂起等待状态,但是在实例创建以后,获取实例的方法就没必要再进行同步控制了;所以,可以考虑把同步锁往下放,放到产生实例的语句块上,来形成一个同步语句块锁;

public class SynchronizedSingleton {

    //一个静态的实例
    private static SynchronizedSingleton synchronizedSingleton;
    //私有化构造函数
    private SynchronizedSingleton(){}
    //给出一个公共的静态方法返回一个单一实例
    public static SynchronizedSingleton getInstance(){
        if (synchronizedSingleton == null) { //(1)
            synchronized (SynchronizedSingleton.class) { //同步语句块  
                if (synchronizedSingleton == null) { //这里进行了又一次判断,是为了防止线程A创建完实例释放同步锁,线程B已经过了语句“(1)”的判断进入同步块继续创建实例;
                    synchronizedSingleton = new SynchronizedSingleton();
                }
            }
        }
        return synchronizedSingleton;
    }
}

假设我们去掉同步块中的是否为null的判断,有这样一种情况,假设A线程和B线程都在同步块外面判断了synchronizedSingleton为null,结果A线程首先获得了线程锁,进入了同步块,然后A线程会创造一个实例,此时synchronizedSingleton已经被赋予了实例,A线程退出同步块,直接返回了第一个创造的实例,此时B线程获得线程锁,也进入同步块,此时A线程其实已经创造好了实例,B线程正常情况应该直接返回的,但是因为同步块里没有判断是否为null,直接就是一条创建实例的语句,所以B线程也会创造一个实例返回,此时就造成创造了多个实例的情况。

[以上内容摘自博客园:http://www.cnblogs.com/zuoxiaolong/p/pattern2.html ]

原文地址:https://www.cnblogs.com/crazytrip/p/6676838.html