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;
                }

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

  • 相关阅读:
    flex布局中transform出错
    RabbitMQ系列之Centos 7安装RabbitMQ 3.6.1
    解决windows下FileZilla server中文乱码问题
    IIS 7.5 + PHP-5.6.3 + mysql-5.6.21.1
    C# 速编神器LinqPad(新版6.5)
    一个MySql Sql 优化技巧分享
    IIS反向代理/Rewrite/https卸载配置
    zerotier 远程办公方案
    一次Mysql连接池卡死导致服务无响应问题分析(.Net Mysql.Data 6.9.9)
    ExpressCache
  • 原文地址:https://www.cnblogs.com/ServiceboyNew/p/3734364.html
Copyright © 2011-2022 走看看