无锁,线程安全,延迟加载的单例实现(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 ...
随机推荐
- MySQL无法登录服务器解决方法
提示:#2000 无法登录 MySQL 服务器 今天用本机装了个phpMyAdmin,版本3.4.8,想用它来连一台内网服务器上的Mysql,于是乎修改phpMyAdmin配置文件config.inc ...
- WearableListView的使用和一些思考
今年加盟了一家做手表的公司,至此开启了androidwear(类)的开发之门. 近日要做一个手表上的List显示,为此也是花了很多的心思在List效果上,多日下来,有些心得. 一.需求确定: 手表上的 ...
- C#部分方法定义
C#部分方法定义 部分类也可以定义部分方法.部分方法在部分类中定义,但没有方法体,在另一个部分类中执行.在这两个部分类中,都要使用partial关键字. public partial class My ...
- Swift - 27 - 使用元组让函数返回多个值
//: Playground - noun: a place where people can play import UIKit // 定义一个数组 var userScores:[Int]? = ...
- VsCode使用技巧
VsCode版本1.7.2 1. node智能提示:vscode1.7之前的版本智能提示是采用jsconfig.json方式,在右下角会有小灯泡,点击创建jsconfig.json.1.7之后使用Ty ...
- zookeeper集群一次性启动
编写shell脚本 新建文本,命名为start-zookeeper.sh #!/bin/sh echo "start zkServer…" for i in master work ...
- DontDestroyOnLoad
本文由博主(YinaPan)原创,转载请注明出处:http://www.cnblogs.com/YinaPan/p/Unity_DontDestroyOnLoad.html public stati ...
- 你好,C++(33)对象生死两茫茫 6.2.3 一个对象的生与死:构造函数和析构函数
6.2.2 使用类创建对象 完成某个类的声明并且定义其成员函数之后,这个类就可以使用了.一个定义完成的类就相当于一种新的数据类型,我们可以用它来定义变量,也就是创建这个类所描述的对象,表示现实世界中 ...
- C++ Primer 5th 第13章 拷贝控制
当一个对象的引用或者指针离开作用域时,析构函数不会执行. 构造函数有初始化部分(初始化列表)和函数体. 析构函数有析构部分和函数,但析构函数的析构部分是隐式的.
- 78 Subsets(求子集Medium)
题目意思:求解一个数组的所有子集,子集内的元素增序排列eg:[1,3,2] result:[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]思路:这是一个递推的过程 [] ...