无锁,线程安全,延迟加载的单例实现(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 ...
随机推荐
- jquery 的缺点
接口不统一 其中.each();.map();$.each();这些方法的参数函数的参数顺序是index, value这种顺序.但是$.map();方法的参数函数的参数顺序则是value,index这 ...
- iOS在Cocoa Touch Static Library使用CocoaPods
1.在XCode中新建静态库工程:DDLogLib. 2.添加对外暴露接口的头文件DDLogLibHeader.h 3.命令行进入DDLogLib目录,运行pod init,并修改Podfile 4. ...
- 七、C# 接口
并非只能通过继承使用多态性,还能通过接口使用它. 和抽象类不同,接口不包含任何实现(方法). 然后和抽象类相似,接口也定义了一系列成员,调用者可以依赖这些成员来支持一个特定的功能. 实现接口的类会 ...
- Hibernate 环境搭建
Hibernate 工作流程 1.创建工程并导包 2.在src根目录下创建配置文件:hibernate.cfg.xml(也可以创建在src其他文件夹下,但是在后面的配置中,需要指明路径) <?x ...
- bash shell学习-shell script基础 (笔记)
A chain no stronger than its weakest link. "一着不慎,满盘皆输" 参考资料:鸟哥的Linux私房菜 基础学习篇(第三版) Linux ...
- jQuery MVC 科室异步联动
//科室改变,级联医生 js $("#DepartmentId").change(function () { if (isNaN($(this).val())) { $(" ...
- FMDB警告Warning: there is at least one open result set around after performing的问题
FMDB操作sqlite的时候总是报警告Warning: there is at least one open result set around after performing,后来发现是执行查询 ...
- 【行为型】Memento模式
备忘录模式顾名思义就是一种能有备忘作用的设计模式,其目的是在对象外部保存其在某一时刻的状态信息,并且在任何需要的时候,都可以通过备忘录中保存的状态数据恢复对象在当时情形下的状态. 备忘录模式旨在对象的 ...
- 使用飞信api接口实现短信发送(只能发送好友)
找了很久才找到一个能用的飞信API接口(http://quanapi.sinaapp.com/fetion.php?u=飞信登录手机号&p=飞信登录密码&to=接收飞信的手机号& ...
- SCJP_104——题目分析(3)
11. what is reserved words in java?A. run B. default C. implement D. import Java 中,给标识符取名的时候,不能使用关键字 ...