• C#单例测试(懒汉式双锁保证线程安全)


    单例模式的概念

    单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

    关键点

    • 这个类只有一个实例,这是最基本的
    • 它必须自行创建这个实例,外部不能实例化
    • 进程内唯一

    代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace WCF_Host_Service
    {
        /// <summary>
        /// 服务程序唯一上下文对象(单例)
        /// </summary>
        public sealed  class ServiceContext
        {
            private static ServiceContext _ServiceContext = null;
            private readonly static object lockObj = new object();
            /// <summary>
            /// 禁止外部进行实例化
            /// </summary>
            private ServiceContext()
            {
    
            }
            /// <summary>
            /// 获取唯一实例,双锁定防止多线程并发时重复创建实例
            /// </summary>
            /// <returns></returns>
            public static ServiceContext GetInstance()
            {
                if (_ServiceContext == null)
                {
                    lock (lockObj)
                    {
                        if (_ServiceContext == null)
                        {
                            _ServiceContext = new ServiceContext();
                        }
                    }
                }
                return _ServiceContext;
            }
        }
    }

    关键点: 1)私有的构造函数 2)两次进行唯一实例的内部成员变量是否为空的判断。第二次判断时是在lock的前提下进行的。所以是唯一的,这次判断保证了是否为空的结论是线程安全的。

    测试过程

    ConcurrentDictionary<int, ServiceContext> dict = new ConcurrentDictionary<int, ServiceContext>();
                    Action testTask = () =>
                    {
                        ServiceContext sc = ServiceContext.GetInstance();
                        if (sc != null && !dict.ContainsKey(sc.GetHashCode()))
                        {
                            dict.TryAdd(sc.GetHashCode(), sc);
                        }
                        Thread.Sleep(1);
                    }; 
                    int index = 0;
                    while (index < 1024)
                    {                    
                        Parallel.Invoke(testTask,testTask);
                        index++;
                    }
                    Debugger.Log(0,"",string.Format("测试共生出{0}个实例。",dict.Count));

    利用反射外部强制实例化测试:

    var type = this.GetType().Assembly.GetType(typeof(ServiceContext).FullName);
                        var sc = Activator.CreateInstance(type);

  • 相关阅读:
    简单对拍
    搜索感想
    L1434滑雪
    记忆化搜索
    L3956棋盘
    USACO 数字三角形
    枚举顺序
    蓝桥计算
    用户态和内核态IO过程
    Mybatis的结果集中的Do要不要有setter
  • 原文地址:https://www.cnblogs.com/datacool/p/datacool_2017_notedl.html
Copyright © 2020-2023  润新知