随笔 - 268  文章 - 0  评论 - 1028  阅读 - 160万

浅谈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、对自己说:
加油。

posted on   JeffWong  阅读(19787)  评论(25编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
< 2010年9月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9

I know how to make it works and I want to know how it works.
点击右上角即可分享
微信分享提示