你真的了解单例模式吗?你真的认为单例模式很简单吗? 第二篇

你真的了解单例模式吗?你真的认为单例模式很简单吗? 第二篇

接着说我们的单例故事。
想要解决上面的线程不安全问题,有很多种办法,这里我们一一来探讨。
第一种就是通过synchronized来控制线程安全,将synchronized加在getInstance方法上,
public static synchronized SingleFactory getInstance()
运行下之前的main方法,是不是发现hashCode都一样了?开心吧,这么严重的问题一下子就解决了。
~~~~
再来一盆冷水:
这种做法其实效率很低。因为在任何时候只能有一个线程调用该方法,其余的需要加入等待,阻塞程度可想而知,如何解决这个问题呢?
我们来分析下,一般这种单例模式都会用在什么场合?是不是初始化的时候?
好的,我们姑且就认为是初始化的时候,即第一次调用的时候创建对象,后续只存在调用的操作。那么就印出来我们之前提到的双重检验
锁。

双重检验锁
双重检验锁(double checked locking pattern),是一种使用同步块加锁的方法。之所以称之为双重检验锁,是
因为会有两次检验 instance == null 的操作。一次是在同步块外面,一次是在里面。
先来上代码:

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

运行后是不是发现也ok?
好了,我们来说一下为什么要在同步块外面一次,里面又来一次。
因为当我们第一次初始化的时候,可能会有多个线程同时进入外部的if判断中,如果这个时候没有对当前类进行同步块加锁,则很容易就出现多
个实例的状态。因此我们需要在外面做次判断,然后判断里面加上一个同步块。

~~~~
再来一盆冷水。
为啥?上面的代码看起来很严谨,很完美啊,为什么还是不对?
呵呵,too young too simple!
欲知后事,且听下回分解。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值