单例模式

单例模式: 一个类只创建一个对象,构造方法私有
1.饿汉模式
加载字节码文件时就创建对象

public class Singleton1 {
    // 1.私有化构造方法
    private Singleton1(){}
    // 写一个私有的Singleton1类型的成员变量
    private static final Singleton1 INSTANCE = new Singleton1();
    // 2. 对外提供公共的静态方法,返回值就是A的唯一实例
    public static Singleton1 getInstance(){
        return INSTANCE;
    }
}

2.懒汉模式
初始化第一个对象实例的时候创建对象

public class Singleton2 {
    // 1.私有化构造方法
    private Singleton2() {}
    // 写一个私有的Singleton1类型的成员变量
    private volatile static Singleton2 instance = null;	//volatile 关键字禁止重排序
    // 2. 对外提供公共的静态方法,返回值就是A的唯一实例
    // t1 t2
    public static Singleton2 getInstance() {
        // 3. 判断是否是第一次获取/使用该实例
        // t1 t2 t2发现instance不为null,跳过这段代码,直接返回
        if (instance == null) {                   //此处判断目的:保证效率。只让实例化instance之前线程安全即可。
            // t1
            synchronized (Singleton2.class) {   //加锁的目的:线程安全。是为了保证在多线程环境下,下属代码同时只有一个线程在操作
                /**
                 * 下列三行代码可能会出现线程安全问题,但是只有再instance没有被实例化之前才会出现
                 * 上述加锁,太武断了
                 */
                // t1 -l 执行完指令1 和3 之后失去了CPU的执行权,instance不再为null,但是instance对象不完整。
                if (instance == null) {         // 此处判断的目的:保证instance只被创建一次
                    // t1 -l
                    instance = new Singleton2();
                }
            }
        }
        // t2返回的就是不完整的instance,使用时会出现问题。
        return instance;
    }
}
/*
 *  Double Check Lock   双重校验加锁
 *      只有要求线程安全的同时,并且保证较高的效率,都可以使用DCL
 *
 *
 *  指令重排
 *      jvm、cpu在执行代码期间,为了提高执行效率,会把某些指令乱序执行。
 *
 *  user = new User();
 *  上述代码执行步骤如下:
 *      1. 开辟内存空间,生成空间首地址值 new
 *      2. 初始化内存空间的内容 User(xxx)
 *      3. 把上述空间的首地址值,赋值给user
 *
 *      正常的指令执行顺序:1  -   2  -  3
 *      重排后指令执行顺序:1  -   3  -  2
 *
 *  volatile功能之一:禁止指令重排
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值