首页 新闻 会员 周边 捐助

双重锁定真的有意义吗

0
[已解决问题] 解决于 2015-06-17 11:36

众所周知,在单例模式中,为了解决多线程造成的创建出多个对象的问题,一般会使用锁机制来强行同步,锁加载方法上浪费性能,于是会lock创建对象的代码块,形如:

lock(obj){

  if(instance == null){instance = new Object();}

}

于是就有人提出,2个线程模型下(A和B),A线程取得锁,并创建完对象,释放锁,B线程拿到锁,还要拿到锁,再判断instance==null,浪费性能,于是就改造出了双重锁定的东西,形如:

if(instance == null){

  lock(obj){

    if(instance == null){instance = new Object();}

  }

}

我想问:

A线程拿到锁之后,还没来得及判断instance==null,CPU的控制权就被B线程获得,然后B线程等待A线程释放锁,A线程继续创建instance,然后B线程还不是会继续取得锁,判断null,这个双重锁定有个什么用?

请高人指点一二!不胜感激!

Thirty的主页 Thirty | 菜鸟二级 | 园豆:252
提问于:2015-06-16 22:48
< >
分享
最佳答案
2

第一个判断null是为了尽量减少进入锁的线程数;

第二个判断null是为了防止进入锁只有的多个线程重复创建实例;

奖励园豆:5
傲慢与偏剑 | 菜鸟二级 |园豆:381 | 2015-06-17 09:19

 

回答的很简洁明白,谢谢

Thirty | 园豆:252 (菜鸟二级) | 2015-06-17 11:35
其他回答(3)
0

是在不为空的时候系统就不会出现锁,而且不为空的情况是最多的

吴瑞祥 | 园豆:29449 (高人七级) | 2015-06-17 07:39
0

1、A线程和B线程获取instance,此时如果instance为空,假设A线程先拿到锁,然后判断instance为空,则创建一个对象,接着释放锁;紧接着B拿到锁,此时判断instance为空不成立,直接释放锁并返回,明显少创建了一次对象。Double Check的目的是在临界状态下少创建对象。

2、经过步骤1,instance不为空,外面的那个判断if(instance == null)不成立,直接返回instance,可以减少锁定,提高性能

JeffWong | 园豆:2328 (老鸟四级) | 2015-06-17 09:21

懂了,第一层if是为了减少锁定

支持(0) 反对(0) Thirty | 园豆:252 (菜鸟二级) | 2015-06-17 11:35
0

多线程中对同一个对象,在加锁之前的所有判定都是不靠谱的。因为加锁之前别的线程可以对这个对象做任何事情。

司幸 | 园豆:319 (菜鸟二级) | 2015-06-17 10:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册