zoukankan      html  css  js  c++  java
  • 关于“单例模式”的另外一种实现

      传统单例模式的实现有懒汉、饿汉等模式,也有双锁机制(防止不必要的线程再度进入锁的临界区实例化单例模式的全局变量)。不过据说(未经考证)在VS中CPU开启“out-of-order execution”,仍然会导致出问题,原因在于:

      我们假设a和b线程同时试图初始化单例模式的全局变量,a先进入方法获得了锁,b慢了一拍,判断全局变量!=null之后只能徘徊在外边直到a好了位置。我们设想a线程初始化应该的步骤:

           1)调用构造函数,产生实例对象。

       2)为全局变量分配栈和堆上的空间。

      3)将全局变量指向产生的实例对象。

      但是,可惜的是,一旦该优化开启之后,编译器变得“不听话了”,它会先1:为实例对象分配好空间,然后2:直接把全局变量指针指向该空间,最后3:才调用构造函数去“充实”实例。设想一下,如果是这样的话,b徘徊在外边,等到线程a刚完成2,b就发现全局变量已经不为null了!但是实例化构造函数尚未调用(或者调用中),结果会如何?!

      因此,如果没有必要延时加载,用“饿汉模式”或者直接写入静态构造函数的“懒汉模式”最好,否则需要根据动态反射等机制的,建议使用InternLock,类似以下代码:

     if(_instance==null)
                {
                    Interlocked.CompareExchange<AbsDatabaseFactory>(ref _instance, (AbsDatabaseFactory)Assembly.LoadFile(pathwithFileName).CreateInstance(classTypeName), null);
                    Instance = _instance;
                    ConnectionString = connectionString;
                }

      考虑到这是微软的方法,因此速度特快(尽管也有可能冒着“诞生几个类”的可能),但是应该不会出现错误的。大家以为呢?

  • 相关阅读:
    GitLab版本管理
    Failed to add reference to 'System.Net.Http'. Please make sure that it is in the Global Assembly Cache.
    在CentOS 6.3中安装拼音输入法
    Yum Error Another app is currently holding the yum lock; waiting for it to exit
    Centos使用光盘作为本地yum源
    Linux操作系统桌面环境GNOME和KDE的切换
    CentOS安装VMware Tools
    CentOS 加载/挂载光驱
    svn Couldn't open rep-cache database
    linux内存排查工具valgrind
  • 原文地址:https://www.cnblogs.com/ServiceboyNew/p/3734364.html
Copyright © 2011-2022 走看看