首页 新闻 会员 周边 捐助

关于单例模式的一个疑问

0
悬赏园豆:30 [已解决问题] 解决于 2014-12-24 15:20
public class Singleton
{
       private static Singleton instance;
       private static object _lock=new object();

       private Singleton()
       {

       }

       public static Singleton GetInstance()
       {
               if(instance==null)
               {
                      lock(_lock)
                      {
                             if(instance==null)
                             {
                                     instance=new Singleton();
                             }
                      }
               }
               return instance;
       }
}

上面是所谓的懒汉单例模式,我疑惑的是:外层的if判断是原子操作吗?有没有可能线程1进行if判断的时候执行到一半,然后时间片用完,线程2得到执行权……这不就有问题吗?

加州招待所的主页 加州招待所 | 初学一级 | 园豆:134
提问于:2014-12-21 20:54
< >
分享
最佳答案
0

很赞成 @Qlin的说法!因为加了锁,线程2是得不到执行权的,只能等待锁释放。。

收获园豆:30
幻天芒 | 高人七级 |园豆:37207 | 2014-12-22 11:41

假设外层的if判断不是原子操作,某一时刻,线程1和线程2都试图去执行外层if语句,竞争的结果是线程2得到CPU执行权,线程1在外层if语句处挂起(1挂起的时候instance还是空),2进入内层循环,2执行完毕,创建了一个实例,释放锁,然后1得到CPU执行权,由于1挂起的时候instance是空,所以对1来说外层if成立,进入内层循环,又创建了一个实例。这样就会导致有两个实例。

如果if(a==b)不是原子操作,我说这种情况应该是存在的。如有错误,请您指教。

加州招待所 | 园豆:134 (初学一级) | 2014-12-23 22:24

@钱智慧: 1挂起的时候instance为空,进入内层的时候,instance不为空了。所以里面的那个if就起到作用了。所以就不会有两个实例了~

幻天芒 | 园豆:37207 (高人七级) | 2014-12-23 22:53

@幻天芒: 谢谢您 ,明白了。

加州招待所 | 园豆:134 (初学一级) | 2014-12-24 15:20

@钱智慧: 外层if不是这种形式单例的必须,关键是锁里面的那个if,由于加锁很费时间,在外层进行一个空判断的话,可以减少加锁的次数。

幻天芒 | 园豆:37207 (高人七级) | 2014-12-25 08:52
其他回答(3)
0

cpu是单线程,只不过操作系统模拟出来的多线程,所以你说的问题不存在

刘宏玺 | 园豆:14020 (专家六级) | 2014-12-21 21:48
0

就是因为怕这种问题 不是下面有一个lock么

小眼睛老鼠 | 园豆:2731 (老鸟四级) | 2014-12-21 21:56

假设外层的if判断不是原子操作,某一时刻,线程1和线程2都试图去执行外层if语句,竞争的结果是线程2得到CPU执行权,线程1在外层if语句处挂起(1挂起的时候instance还是空),2进入内层循环,2执行完毕,创建了一个实例,释放锁,然后1得到CPU执行权,由于1挂起的时候instance是空,所以对1来说外层if成立,进入内层循环,又创建了一个实例。这样就会导致有两个实例。

如果if(a==b)不是原子操作,我说这种情况应该是存在的。如有错误,请您指教。

支持(0) 反对(0) 加州招待所 | 园豆:134 (初学一级) | 2014-12-23 22:27
0

不要外层的 if 也可以。

外层的if  作用:可以防止进入lock,lock 需要耗资源的,每次访问实例时 ,如果有对象了,就可不进lock,性能考虑。

里层的if才是单例的防止, 为了创建一个实例。

Qlin | 园豆:2403 (老鸟四级) | 2014-12-22 09:19

假设外层的if判断不是原子操作,某一时刻,线程1和线程2都试图去执行外层if语句,竞争的结果是线程2得到CPU执行权,线程1在外层if语句处挂起(1挂起的时候instance还是空),2进入内层循环,2执行完毕,创建了一个实例,释放锁,然后1得到CPU执行权,由于1挂起的时候instance是空,所以对1来说外层if成立,进入内层循环,又创建了一个实例。这样就会导致有两个实例。

如果if(a==b)不是原子操作,我说这种情况应该是存在的。如有错误,请您指教。

支持(0) 反对(0) 加州招待所 | 园豆:134 (初学一级) | 2014-12-23 22:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册