zoukankan      html  css  js  c++  java
  • 浅谈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、对自己说:
    加油。

    作者:Jeff Wong 
    出处:http://www.cnblogs.com/jeffwongishandsome/ 
    本文版权归作者和博客园共有,欢迎围观转载。转载时请您务必在文章明显位置给出原文链接,谢谢您的合作。

  • 相关阅读:
    49. 字母异位词分组
    73. 矩阵置零
    Razor语法问题(foreach里面嵌套if)
    多线程问题
    Get json formatted string from web by sending HttpWebRequest and then deserialize it to get needed data
    How to execute tons of tasks parallelly with TPL method?
    How to sort the dictionary by the value field
    How to customize the console applicaton
    What is the difference for delete/truncate/drop
    How to call C/C++ sytle function from C# solution?
  • 原文地址:https://www.cnblogs.com/miralce/p/2887012.html
Copyright © 2011-2022 走看看