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.单例类必须自己创建 ...
随机推荐
- 【代码工具】Lombok来优雅的编码
前言 Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注解实现这一目的. 正文 添加依赖 在 pom.xml ...
- NX二次开发-UFUN发射线函数UF_MODL_trace_a_ray的用法
今天是国庆节,放假休息懒得动,没有出去玩,在家研究一下发射线函数UF_MODL_trace_a_ray.小弟以前在软件公司混的时候,当时我做的那个项目就用到了UF_MODL_trace_a_ray,当 ...
- NX二次开发-NXOpen::WCS Class Reference
NX11+VS2013 #include <NXOpen/Part.hxx> #include <NXOpen/PartCollection.hxx> #include < ...
- 'ddkbuild.cmd' 不是内部或外部命令,也不是可运行的程序
转自VC错误:http://www.vcerror.com/?p=49 问题描述: 错误:'ddkbuild.cmd' 不是内部或外部命令,也不是可运行的程序 解决方法: 详细的解决方法可参考VC错误 ...
- Portainer Exec Container 失败解决方案
近日,将portainer服务挂了个域名,然后用Nginx代理的时候发现不能attach容器了,经过搜索在issue 找到解决方案 1.修改Nginx config server { listen 8 ...
- jsp-提交表单乱码解决
jsp提交表单有两种方式,一种是get,一种是post,对于两种方式都可能出现乱码,以下给出两种乱码方式的解决方案. 1.post提交解决乱码 //设置解码方式,post提交解决乱码 比较简单 req ...
- Linux下修改Mysql的用户(root)的密码(转载)
修改的用户都以root为列.一.拥有原来的myql的root的密码: 方法一:在mysql系统外,使用mysqladmin# mysqladmin -u root -p password " ...
- js 本地预览图片和得到图片实际大小
//填充预览图片 function adpter(file, upfile) { var imgName = new Date().getTime() + file.name.substr(file. ...
- node---处理post请求
//nodejs 处理post请求 // 异步 const http =require('http') const server=http.createServer((req,res)=>{ i ...
- code+第四次网络赛div2
T1 组合数问题: 用k个不完全相同的组合数表示一个数n. 用k-1个1和一个n-k+1表示即可. #include<cstdio> using namespace std; int x, ...