设计模式之单例模式面试总结

单例模式

class SingleInstance {

private static SingleInstance instance;

    private SingleInstance() {

    }

    public static SingleInstance getInstance() {
        if (instance == null) {                                          (i)
            synchronized (SingleInstance.class) {
                if (instance == null) {
                    instance = new SingleInstance();                     (j)
                }
            }
        }
        return instance;                                                 (k)
    }
}

1、不加任何同步锁的时候,当有两个线程同时执行到(j)处时,会创建两个instance实例对象。

2、双重检查也不是绝对安全的,因为JVM编译器可能对执行进行重排,new一个对象时不是原子操作

一个对象的初始化正常顺序:
(1)memory=allocate();//分配对象的内存空间
(2)ctorinstance(memory)//初始化对象
(3)设置栈上的引用指向刚分配的内存地址。
但是重排后可能会出现:
(1)memory=allocate();//分配对象的内存空间
(3)设置栈上的引用指向刚分配的内存地址。
(2)ctorinstance(memory)//初始化对象。
  如果线程A执行到(i)处,线程B执行到(j)处,并且线程B执行了重排列后的指令(1)(3),这时A线程抢到CPU资源,判空时,发现instance不为空,就直接返回(K)处的instance对象,由于这个对象是未初始化过的对象,那么在用该对象调用实例方法时,就会出现程序异常。

3、双重检查加锁“的方式可以既实现线程安全(不保证绝对安全),又能够使性能不受到很大的影响。
  双重检测机制在获取对象实例的时候,先判空,如果对象实例为空时才同步,不为空时直接返 回对象,并不是像单层的那样每次获取都要同步,这样减少了每次进入都要同步的时间。

4、加了双重检测机制还可能不安全,那么可以在声明对象的前面加一个volatitle关键字
    这个关键字可以可以防止指令重排,也可以保证线程访问的变量值是主内存中的最新值。那么在双重检测的基础上,就能够保证线程的安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值