无锁,线程安全,延迟加载的单例实现(C#)
单例(singleton)是非常常见,也非常有用的设计模式,当然了, 面试中也是经常会被问到的:)在几乎所有的项目中都能看到它的身影。简而言之,单例保证了一个自定义类型在整个程序的生命周期只被创建一次。要实现一个简单的单例是也很容易的:
public class Example
{
private static Example instance; private Example()
{
} public static Example Instance
{
get
{
if (instance != null)
{
instance = new Example();
} return instance;
}
}
}
这是大多数人的写法。
这是一个延迟加载的单例。换句话说,只有当调用Example.Instance时,才会创建Example的实例。当不存在多线程调用的情况下,这个单例是工作得很好的。但是在现实中,我们已经很少不去考虑线程安全了。提到线程安全,我们第一反应就是加锁:
public class Example
{
private static Example instance; private object myLock = new object(); private Example()
{
} public static Example Instance
{
get
{
lock(myLock)
{
if (instance != null)
{
instance = new Example();
} return instance;
}
}
}
}
这显然是没有问题的,我相信也是大多数程序员的做法。
在面试中如果面试者能够在没有任何提示下给出这个线程安全且延迟加载的单例,已经很让面试官满意了。 可是我想再吹毛求疵下:能不能实现一个无锁的线程安全单例?
无锁且要线程安全。。。我们需要借助语言的特性。(实际上代码更少了)
public class Example
{
private static Example instance = new Example(); private Example()
{
} public static Example Instance
{
get
{
return instance;
}
}
}
的确,无锁且线程安全了,但是。。。延迟加载似乎又缺失了。也许有人要问,这个延迟加载有什么用?
绝大多数情况下,这个延迟加载没有任何用(面试虐人除外),除非这个类还有其他static public methods。譬如说这个Example类有一个静态方法:
public static string Output()
{
string str;
// process the str.
return str;
}
并且我们只会用到Example.Output()。在这种情况下如果 Example 的instance被创建了,显然是浪费内存。据我所知,这是延迟加载唯一有用的地方。
不管这个延迟加载用处有多大,我们单纯从研究的角度考虑,是否能既做到无锁,线程安全,又延迟加载?
C#语言的另一大特性帮助了我们:嵌套类。直接上代码:
public class Example
{
private static Example instance; private Example()
{
} public static Example Instance
{
get
{
return Nested.Instance;
}
} class Nested
{
static Nested()
{
} internal static readonly Example Instance = new Example();
}
}
无锁,线程安全,延迟加载的单例实现(C#)的更多相关文章
- c++:自己动手实现线程安全的c++单例类
前段时间使用c++做项目开发,需要根据根据配置文件路径加载全局配置文件,并对外提供唯一访问点.面对这样一个需求,自然的就想到了使用单例模式来创建一个单例配置对象,供外部调用.一开始想使用boost中自 ...
- iOS-主线程刷新UI【+单例】
主线程刷新UI dispatch_async(dispatch_get_main_queue(), ^{ /// }); 单例 static Tools *_sharedManger; @implem ...
- MVC 创建线程内的db单例
using System; using System.Collections.Generic; using System.Linq; using System.Web; using LSUnion.S ...
- java设计模式--解决单例设计模式中懒汉式线程安全问题
首先写个单例,懒汉模式: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} pu ...
- 依赖注入及AOP简述(九)——单例和无状态Scope .
三.依赖注入对象的Scope及其生命周期 在前面的章节我们讲到,依赖注入容器之所以能够区别于以往的ServiceLocator等容器,是在于其不但能够自动构建多层次的.完整的依赖关系图,并且可以管理依 ...
- GOF设计模式之1:单例设计模式
1.单例设计模式核心作用: 保证一个类只有一个实例,并且提供了访问该实例的全局访问点 2.常见应用场景: window的任务管理器 项目中读取配置文件一般也是一个单例模式 数据库连接池的设计也是采用单 ...
- Java设计模式:Singleton(单例)模式
概念定义 Singleton(单例)模式是指在程序运行期间, 某些类只实例化一次,创建一个全局唯一对象.因此,单例类只能有一个实例,且必须自己创建自己的这个唯一实例,并对外提供访问该实例的方式. 单例 ...
- 十次艳遇单例设计模式(Singleton Pattern)
1.引言 单例设计模式(Singleton Pattern)是最简单且常见的设计模式之一,在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访 ...
- Java单例和多例
背景:最近在学习韩老师的笔记时候发现不是很了解单例和多例,于是通过网上查找资料的方式去学习. 设计模式:最佳的实践,是软件开发人员在软件开发过程中面临一般解决方案,也就是开发的经验总结. 单例模式(S ...
随机推荐
- ecshop首页调用指定商品分类下的商品品牌列表
转之--http://www.16css.com/ecshop/735.html 通过二次开发可以实现ECSHOP首页调用指定分类下的品牌列表. 第一步: 打开根目录下的index.php 在最后面 ...
- PHPexcel数据按模板导出
<?php header("Content-type: text/html; charset=gb2312"); error_reporting(E_ALL); ini_se ...
- CompareValidator ASP控件
定义和用法 CompareValidator 控件用于将由用户输入到输入控件的值与输入到其他输入控件的值或常数值进行比较. 注释:如果输入控件为空,则不会调用任何验证函数,并且验证将成功.使用 Req ...
- 数据类型的转换String
x.toString(): 无法转换null和undefined 不过String()却是万能的,其中的原理如下 function String(x){ if(x===undefined){ retu ...
- 重拾C++ 基础知识总结(一)
1.使用gcc编译c++文件报错 proc1.cc:(.text+0x14): undefined reference to `std::cout' C++程序使用gcc命令只能编译,不能链接库文件 ...
- Neutron/ML2学习
Neutron/ML2 Neutron ML2 模块层2(ml2)插件是一种允许OpenStack网络同时地利用在复杂现实数据中心发现的各种第二层网络技术的框架.目前它与存在的openvswitch. ...
- 如何做好Flex与Java交互
三种flex4与Java顺利通信的方式是: flex与普通java类通信RemoteObject; flex与服务器交互HTTPService; flex与webservice交互WebService ...
- asp.net实现 EXCEL数据导入到数据库功能
在项目中经常要用EXCEL导入数据到数据库,提高工作效率. 注意:EXCEL中的第一行不能导入. 下面是源码: IntoExcel.aspx: [csharp] <%@ Page Languag ...
- Day4 内置函数补充、装饰器
li = [11,22,33,44]def f1(arg): arg.append(55)#函数默认返回值None,函数参数传递的是引用li = f1(li) print(li) 内置函数补充: ...
- 网络流的一个很厉害的ppt
链接: http://pan.baidu.com/s/1dECtMpz 密码: hdbm