浅谈c#中使用lock的是与非

1、从“最简单”的单例模式说起:

public   class  Singleton
{
    
private   static  Singleton instance  =   null ;
    
private   static   readonly   object  syncRoot  =   new   object ();

    
private  Singleton()
    {
    }

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

  稍微了解设计模式基础知识的人对上面的代码应该不会陌生。上次去面试,主考官就让楼猪写个单例。虽然平时已经很久没有刻意去使用设计模式编程了,但是对于这个单例模式,咩哈哈,虽然大丈夫喜怒不形于色,但是nc楼猪当时那个意气风发踌躇满志运笔如飞锋芒毕露啊,嘿嘿,中规中矩地交了如上答案。面试官看了一下肯定了两句,话锋一转,问lock那里的object实例可以直接用instance替代吗?new一个object是否多余,可否写成下面的形式:

public   class  Singleton
{
    
private   static  Singleton instance  =   null ;
    
// private static readonly object syncRoot = new object();

    
private  Singleton()
    {
    }

    
public   static  Singleton GetInstance()
    {
        
if  (instance  ==   null )
        {
            
lock  (instance) // instance能替换syncRoot吗?
            {
                
if  (instance  ==   null )
                {
                    instance 
=   new  Singleton();
                }
            }
        }
        
return  instance;
    }
}

  虽然在这个问题前面,面试官问的一个数据库设计和几个c#的小问题(有一个题楼猪当时竟然嘴硬说那是“奇技淫巧”,好怕怕)很见知识深度和修养,楼猪已经小有提防,但是这个问题还是再次让楼猪自乱阵脚。以前从来没人问过楼猪这个问题,楼猪也没主动想过它,脑袋里一片白茫茫,刚想要镇定下来,面试官又把相同问题问了一遍。不及细想,虽然不能确定,但是还是回答“应该可以...吧”(语气助词用得妙啊)。
  肯定是对这个回答和回答的语气不满意,面试官又提醒问lock机制是什么样的,说说c#大概是怎么实现lock的。楼猪语无伦次说lock本质上和操作系统相关,lock就是当前线程将资源独占其他线程不能访问该锁定资源云云,背书都不会背了吗?无语了。面试官说回去自己试试吧。听他的语气,答案当然不言自明了,小心灵遭受重大挫折和打击啊。
  回来后,验证了一下面试官的问题,程序运行到lock的时候,抛出ArgumentNullException异常,“值不能为null”。为什么lock一个指向null的引用实例不可以呢?
      查了一下中文msdn

lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。


     老实说,直到看到最后一句“对象被释放”才给了楼猪提示。某一对象可以指向null引用,但是null关键字是不需要释放的吧?!是吗?查了一下高人anytao的博客,发现这篇认识全面的null给出了明确的答案。
      接着楼猪又查看了一下经常可以替代lock的Monitor类,赫然发现它的静态方法Enter(object obj)有一个异常类型ArgumentNullException,早知道,也不会那么狼狈啊。

2、lock的陷阱
除了msdn里提到的lock需要注意的两点外,园子里早就有高手总结过了,可以参考这一篇

3、最后自己总结得出的三个结论:
a、c#中null是不能lock的(null会分配内存吗,会占用系统资源吗?和楼猪一起思考和探讨吧)。
b、高手一出手,往往可以化腐朽为神奇。
c、对自己说:
加油。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值