C#の单例模式
版本一:
/// <summary>
/// A simple singleton class implements.
/// </summary>
public sealed class Singleton
{
private static Singleton _instance = null;
/// <summary>
/// Prevents a default instance of the
/// <see cref="Singleton"/> class from being created.
/// </summary>
private Singleton()
{
}
/// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance
{
get { return _instance ?? (_instance = new Singleton()); }
}
}
以上的实现方式适用于单线程环境,因为在多线程的环境下有可能得到Singleton类的多个实例。假如同时有两个线程去判断
(null == _singleton),并且得到的结果为真,那么两个线程都会创建类Singleton的实例,这样就违背了Singleton模式“唯一实例”的初衷。
版本二:
/// <summary>
/// A thread-safe singleton class.
/// </summary>
public sealed class Singleton
{
private static Singleton _instance = null;
private static readonly object SynObject = new object(); Singleton()
{
} /// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance
{
get
{
// Syn operation.
lock (SynObject)
{
return _instance ?? (_instance = new Singleton());
}
}
}
}
以上方式的实现方式是线程安全的,首先我们创建了一个静态只读的进程辅助对象,由于lock是确保当一个线程位于代码的临界区时,另一个线程不能进入临界区(同步操作)。如果其他线程试图进入锁定的代码,则它将一直等待,直到该对象被释放。从而确保在多线程下不会创建多个对象实例了。只是这种实现方式要进行同步操作,这将是影响系统性能的瓶颈和增加了额外的开销。
版本三:
/// <summary>
/// Double-Checked Locking implements a thread-safe singleton class
/// </summary>
public sealed class Singleton
{
private static Singleton _instance = null;
// Creates an syn object.
private static readonly object SynObject = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
// Double-Checked Locking
if (null == _instance)
{
lock (SynObject)
{
if (null == _instance)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
}
版本四:经典模式
public class Singleton
{
private static Singleton instance;
private Singleton()
{
}
public static Singleton GetInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
解析如下:
1)首先,该Singleton的构造函数必须是私有的,以保证客户程序不会通过new()操作产生一个实例,达到实现单例的目的;
2)因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以可以定义一个私有的静态全局变量instance来保存该类的唯一实例;
3)必须提供一个全局函数访问获得该实例,并且在该函数提供控制实例数量的功能,即通过if语句判断instance是否已被实例化,如果没有则可以同new()创建一个实例;否则,直接向客户返回一个实例。
在这种经典模式下,没有考虑线程并发获取实例问题,即可能出现两个线程同时获取instance实例,且此时其为null时,就会出现两个线程分别创建了instance,违反了单例规则。因此,需对上面代码修改。
版本五:
public class Singleton
{
private static Singleton instance;
private static object _lock=new object();
private Singleton()
{
}
public static Singleton GetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}
上述代码使用了双重锁方式较好地解决了多线程下的单例模式实现。先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。
版本六:饿汉模式
public sealed class Singleton
{
private static readonly Singleton instance=new Singleton();
private Singleton()
{
}
public static Singleton GetInstance()
{
return instance;
}
}
版本七:延迟初始化
/// <summary>
/// Delaies initialization.
/// </summary>
public sealed class Singleton
{
private Singleton()
{
}
/// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance { get { return Nested._instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton _instance = new Singleton();
}
}
版本八:静态初始化
public sealed class Singleton
{
private static readonly Singleton _instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
/// <summary>
/// Prevents a default instance of the
/// <see cref="Singleton"/> class from being created.
/// </summary>
private Singleton()
{
}
/// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance
{
get
{
return _instance;
}
}
}
C#の单例模式的更多相关文章
- C++实现线程安全的单例模式
在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...
- 23种设计模式--单例模式-Singleton
一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- java设计模式之--单例模式
前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...
- 设计模式C#合集--单例模式
单例模式 代码: 第一种: private static Singleton singleton = null; private Singleton() { } public static Singl ...
- 设计模式之单例模式(Singleton)
设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
- GOF23设计模式之单例模式
·核心作用: -保证一个类只有一个实例,并且提供一个访问该实例的全局访问点. ·常见应用场景: -Windows的Task Manager(任务管理器)就是很典型的单例模式 -Windows的Recy ...
- GJM : C#设计模式(1)——单例模式
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- PHP设计模式(四)单例模式(Singleton For PHP)
今天讲单例设计模式,这种设计模式和工厂模式一样,用的非常非常多,同时单例模式比较容易的一种设计模式. 一.什么是单例设计模式 单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
随机推荐
- Struts功能详解——ActionForm
ActionForm ActionForm用于封装用户的请求参数,而请求参数是通过JSP页面的表单域传递过来的.因此应保证ActionForm的参数,与表单域的名字相同. ActionForm ...
- usb基础知识以及枚举过程介绍
一个USB设备有一个设备描述符,设备描述符里面决定了该设备有多少种配置,每种配置描述符对应着配置描述符:而在配置描述符中又定义了该配置里面有多少个接口,每个接口有对应的接口描述符:在接口描述符里面又定 ...
- NX二次开发-UFUN参数选择对话框UF_UI_select_parameters
#include <uf.h> #include <uf_ui.h> #include <uf_modl.h> UF_initialize(); //参数选择对话框 ...
- NX二次开发-UFUN获取显示在NX交互界面的对象UF_OBJ_is_displayable
NX9+VS2012 #include <uf.h> #include <uf_disp.h> #include <uf_obj.h> #include <u ...
- word2vec中关于霍夫曼树的
再谈word2vec 标签: word2vec自然语言处理NLP深度学习语言模型 2014-05-28 17:17 16937人阅读 评论(7) 收藏 举报 分类: Felven在职场(86) ...
- Spring源码由浅入深系列二 类结构
BeanFactory 上一章中,我们提过Spring的依赖注入容器是BeanFactory.BeanFactory是一个基础接口,它有一个默认实现类:DefaultListableBeanFacto ...
- Android Telephony分析(五) ---- TelephonyRegistry详解
本文紧接着上一篇文章<Android Telephony分析(四) —- TelephonyManager详解 >的1.4小节.从TelephonyRegistry的大部分方法中: 可以看 ...
- linux 平台安装JDK环境
1.检查一下系统中的jdk版本 [root@localhost software]# java -version 2.检测jdk安装包 [root@localhost software]# rpm - ...
- verifier 调试内存泄露
没啥技术含量,都是老段子了, 这次记下来,只是我想说,我也做过,留个念相. 前置条件,电脑里面必须得有Verifier,有了之后把自己的驱动加进去, WinDBG上双机,然后就可以跑了,跑一段时间就可 ...
- PROJECT | 四则运算UI设计 - PSP表格&需求分析
PSP表格(TP版) 需求分析 [GUI编程语言选择] 考虑到Java编写GUI效率偏低且界面不算特别美观(即使有Windowbuilder插件帮助),所以我们使用控件更多,开发效率更高,具有集成开发 ...