23种设计模式之单例模式

单例模式:确保一个类最多只有一个实例,并提供一个全局访问点

普通单例模式示例(有问题)

public class Singleton {

    private static Singleton uniqueInstance = null;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

}
示例Singleton
public class ChocolateFactory {

    private boolean empty;
    private boolean boiled;//是否加热过
    private static ChocolateFactory uniqueInstance = null;

    private ChocolateFactory() {
        empty = true;
        boiled = false;
    }

    public static ChocolateFactory getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new ChocolateFactory();
        }
        return uniqueInstance;
    }

    public void fill() {
        if (empty) {
            //添加原料巧克力动作
            empty = false;
            boiled = false;
        }
    }

    public void drain() {
        if ((!empty) && boiled) {
            //排出巧克力动作
            empty = true;
        }
    }

    public void boil() {
        if ((!empty) && (!boiled)) {
            //煮沸
            boiled = true;
        }
    }

}
ChocolateFactory 单利模式示例

单例模式优化多线程问题

使用synchronized同步锁(懒汉式),如果调用同步锁方法次数比较少,还可行,如果调用次数比较多,同步锁是比较耗性能的

public class Singleton {

    private static Singleton uniqueInstance = null;

    private Singleton() {

    }

    public static synchronized Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

}
使用synchronized 同步锁

类加载时初始化(饿汉式),初始化后,如果不用就浪费了

public class Singleton {

    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {
        return uniqueInstance;
    }

}
类加载就初始化

双重检查,加锁法

public class Singleton {

    private volatile static Singleton uniqueInstance = null;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class){
                if(uniqueInstance == null){
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }

}
在加锁前后判断实例是否为空,注意使用了volatile 关键字

还有两种是类静态块和枚举,静态块跟饿汉式差不多,就是在类的静态块实例化对象;枚举用的不多

原文地址:https://www.cnblogs.com/hujiapeng/p/8075004.html