• 双重检查加锁机制


    先举典型的例子,单例模式。

    View Code
     1 public sealed class Singleton
    2 {
    3 private Singleton(){}
    4 private static Singleton instance = null;
    5 private static object syncRoot = new object();
    6
    7 public static Singleton Instance
    8 {
    9 get
    10 {
    11 if (instance == null)
    12 {
    13 lock (syncRoot)
    14 {
    15 if (instance == null)
    16 {
    17 instance = new Singleton();
    18 }
    19 }
    20 }
    21 return instance;
    22 }
    23 }
    24 }

    这里简单说一下,lock(syncRoot) 获取对象syncRoot的互斥锁,可以简单理解为,当多个线程同时执行到lock的时候,大家排队,一个一个地进行。C#中的lock对应于Java中的synchronized。这里在11行与15行进行了重复检查,有些人认为是没有必要的。因为下面的代码是等效的。

     

    View Code
     1 public sealed class Singleton
    2 {
    3 private Singleton(){}
    4 private static Singleton instance = null;
    5 private static object syncRoot = new object();
    6
    7 public static Singleton Instance
    8 {
    9 get
    10 {
    11 lock (syncRoot)
    12 {
    13 if (instance == null)
    14 {
    15 instance = new Singleton();
    16 }
    17 }
    18 return instance;
    19 }
    20 }
    21 }

    那么我们就结合实际的情况来分析一下二者的区别,为了说明方便,以上两种情况分别简称为 “双重检查锁”和“单重检查锁”。 


     1、第一次访问Instance,同时来了10个线程。对于双重检查锁,instance为null,10个线程在这里lock处排队;对于单重检查锁,10个线程在lock处排队。二者是相同的。

    2、第二次、第三次。。。访问Instance,同时来了10个线程。对于双重检查锁,instance不为null,10个线程不用排队,直接返回instance;对于单重检查锁,10个线程,还必须要在lock处排队。

    双重检查锁的优点体现出来了:避免了不必要的排队现象。也就是说,双重检查锁的第一重检查,是很必要的,它来保证不必要的排队。

    举个例子说明,病人到医院看病,第一次去的时候,都要排队去办病历本。以后再去的时候,如果有病历本,就不用再排队去办了。 

  • 相关阅读:
    Log4Net使用指南
    构建Asp.Net2.0 GridView复合多层表头的几种方法
    javaScript中如何定义类
    是不是silverlight 2 的bug
    领悟 JavaScript 中的面向对象
    web拖动Drag&Drop原理
    一个不错的js验证框架
    MySQL中文参考手册
    高效实现数据仓库的七个步骤
    什么是ARP?如何防范ARP欺骗?
  • 原文地址:https://www.cnblogs.com/nzbbody/p/2306154.html
Copyright © 2020-2023  润新知