单例模式

175 阅读1分钟

一、单例模式特点

  1. 构造方法不对外开放,一般是private的
  2. 通过一个静态方法或者枚举返回单例类的对象
  3. 注意多线程模式
  4. 单例类对象在反序列时不会重新创建对象

二、创建单例的几种方法

  1. 懒汉式(线程不安全)
public class Singleton{

    private static Singleton mInstance;
    
    private Singleton(){}

    public static Singleton getInstance(){
        if(mInstance == null){
            mInstance = new Singleton();
        }
        return mInstance;
    }
}
  1. 懒汉式线程安全写法(同步锁的粒度太大)
public class Singleton{

    private static Singleton mInstance;
    
    private Singleton(){}

    public static synchronized Singleton getInstance(){
        if(mInstance == null){
            mInstance = new Singleton();
        }
        return mSingleton;
    }
}
  1. 饿汉式(线程安全)
public class Singleton{

    private static Singleton mInstance = new Singleton();
    
    private Singleton(){}

    public static synchronized Singleton getInstance(){
        return mInstance;
    }
}
  1. 双重检查(DCL)
public class Singleton{

    private volatile static Singleton mInstance;
    
    private Singleton(){}

    public static Singleton getInstance(){
        if(mInstance == null){
            synchronized(Singleton.class){
                if(mInstance == null){
                    mInstance = new Singleton();
                    //1.mInstance 分配实例对象
                    //2.调用Singleton的构造方法
                    //3.Singleton对象赋值给mInstance
                    //在JDK中这个三条指令是乱序的,导致DCL失效, jdk1.5加上volatile关键字,防止指令重排
                }
            }
        }
        return mSingleton;
    }
}
  1. 静态内部类(线程安全,延迟加载)
public class Singleton{
    
    private Singleton(){}
    
    private static Class Holder{
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance(){
        return Holder.INSTANCE;
    }
}

6.枚举enum(默认线程安全且序列化不会重新创建新对象)

enum Singleton{
    INSTANCE;
}