单例模式

单例模式


核心实现

1、构造方法私有化,使其不能在类外部通过new方法实例化该类;

2、定义一个private static的实例化对象;

3、定义一个静态方法用于返回该唯一对象;

饿汉模式(立即加载)

使用类的时候就已经将对象创建完毕,没有多线程同步的问题,但是会持续占着内存;

public class Singleton{
    // 将自身实例化对象设置为一个属性,并且static、final修饰
    private static final Singleton instance = new Singleton();
    // 构造方法私有化
    private Singleton(){}
    // 静态方法返回该实例
    public static Singleton getInstance(){
        return instance;
    }
}

懒汉模式(延迟加载)

调用get方法的时候才会创建对象,在多线程环境中,完全不能保证单例的状态;

public class Singleton{
    // 将自身实例化对象设置为一个属性,并用static修饰
    private static Singleton instance;
    // 构造方法私有化
    private Singleotn(){}
    // 静态方法返回该实例
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

线程安全的懒汉模式

在多线程情况下保证了线程安全,但是synchronized效率很低

public class Singleton{
    // 将自身实例化对象设置为一个属性,并用static修饰
    private static Singleton instance;
    // 构造方法私有化
    private Singleton(){}
    // 静态方法返回该实例,加synchronized关键字实现同步
    public static synchronized Singleton getInstance(){
        if(instance == null){
            instance = new Singleton(); 
        }
        return instance;
    }
}

双端检索机制

DCL (Double check lock)也不一定安全,可能存在指令重排序;

多线程模式的单例模式

public class SingletonDemo{
    // 加了volatile才是安全的
     private static volatile SingletonDemo instance = null;
     private SingletonDemo(){
         
     }
     // 双端检索机制
     public static singletonDemo getInstance(){
         // 线程2进来时,如果没有使用volatile修饰,可能线程1的a操作的1、3部分已经执行,instance不为null,但是没有具体引用;
         if(instance == null){
            synchronized(SingletonDemo.class){
                 if(instance == null){
                     // 这个new操作具体还有三步
                     // 1. 分配对象内存空间
                     // 2. 初始化对象
                     // 3. 设置instance指向的内存地址;
                     instance = new SingletonDemo(); // a操作
                }
            }
        }
         return instance;
    }
 }
posted @ 2021-09-11 20:49  那钢绕指柔  阅读(43)  评论(0编辑  收藏  举报