首页 > 代码库 > 关于“单例模式”的另外一种实现
关于“单例模式”的另外一种实现
传统单例模式的实现有懒汉、饿汉等模式,也有双锁机制(防止不必要的线程再度进入锁的临界区实例化单例模式的全局变量)。不过据说(未经考证)在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; }
考虑到这是微软的方法,因此速度特快(尽管也有可能冒着“诞生几个类”的可能),但是应该不会出现错误的。大家以为呢?
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。