设计模式C#实现(六)——单例模式
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
构成:
1.私有的构造函数
2.私有静态的实例
3.返回实例的静态方法
public class Singleton
{
private static Singleton uniqueInstance = new Singleton();
private Singleton() { Console.WriteLine("this is a new singleton"); }
public static Singleton getInstance()
{
if (uniqueInstance == null)
{
return uniqueInstance;
}
return uniqueInstance;
}
}
这种叫做饿汉模式,实例在类加载时就创建了,缺点是如果实例如果消耗大量的资源而没有使用就会造成浪费,另一种懒汉模式,实例在被使用时才创建,
public class Singleton
{
private static Singleton uniqueInstance;
private Singleton() { Console.WriteLine("this is a new singleton"); }
public static Singleton getInstance()
{
if (uniqueInstance == null)
{
return uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
但是这不是线程安全的
例如
class Program {
static void Main(string[] args) {
while (true) {
Thread t1 = new Thread(Test);
t1.Start();
}
}
static void Test() {
Singleton s = Singleton.getInstance();
}
}
执行的结果有可能是这样

程序创建了多个实例,这不是我们想要的结果,原因是某个线程if (uniqueInstance == null)语句执行后让出了使用权,当它重新获得CPU使用权的时候,可能别的CPU已经创建了实例,而它并不知道,继续执行return uniqueInstance= new Singleton();导致出现多个实例。
因此,要为方法加锁
public class Singleton
{
private static Singleton uniqueInstance;
private Singleton() { Console.WriteLine("this is a new singleton"); }
private static readonly object syncRoot = new object();
public static Singleton getInstance()
{
lock (syncRoot)
{
if (uniqueInstance == null)
{
return uniqueInstance = new Singleton();
}
} return uniqueInstance;
}
}
但是这又带来了一个问题,在实例已经创建完成了,但还是会有大量的线程卡在lock (syncRoot),它们都还会尝试创建实例,这降低了性能
为此,还要为此方法创建另外一个验证
public static Singleton getInstance()
{
if (uniqueInstance == null)
{
lock (syncRoot)
{
if (uniqueInstance == null)
{
return uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
此时,当实例已经创建完成之后,各线程不再访问临界区,提高了性能
单例模式和静态类的比较
1.单例模式可以懒加载,静态类执行更快(为什么?),即在不同条件下二者有不同的性能表现
2.单例可以继承和override
3.单例易于模拟,利于测试
4.单例利于维护状态信息
update:
1.静态类执行更快?
因为静态类在编译时绑定(什么是编译时绑定?)
- Singleton object stores in Heap but, static object stores in stack
- We can clone the object of Singleton but, we can not clone the static class object
- Singleton class follow the OOP(object oriented principles) but not static class
- we can implement interface with Singleton class but not with Static class.
A singleton allows access to a single created instance - that instance (or rather, a reference to that instance) can be passed as a parameter to other methods, and treated as a normal object.
A static class allows only static methods.
设计模式C#实现(六)——单例模式的更多相关文章
- Java并发程序设计(八)设计模式与并发之单例模式
设计模式与并发之单例模式 简单的单例实现: public class Singleton { private Singleton(){ System.out.println("Creatin ...
- Java 设计模式系列(六)适配器模式
Java 设计模式系列(六)适配器模式 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的结构: 类的适配器模式 对象 ...
- 设计模式(一)单例模式:创建模式 ASPNET CORE WEB 应用程序的启动 当项目中 没有STARTUP.CS 类如何设置启动 配置等等
设计模式(一)单例模式:创建模式 先聊一下关于设计的几个原则(1)单一原则(SRP):一个类应该仅有一个引起它变化的原因 :意思就是 (一个类,最好只负责一件事情,并且只有一个引起它变化的原因(2)开 ...
- 设计模式(一)单例模式(Singleton Pattern)
一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设计模式>,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了 ...
- JAVA设计模式(6:单例模式详解)
单例模式作为一种创建型模式,在日常开发中用处极广,我们先来看一一段代码: // 构造函数 protected Calendar(TimeZone var1, Locale var2) { this.l ...
- PHP设计模式(四)单例模式(Singleton For PHP)
今天讲单例设计模式,这种设计模式和工厂模式一样,用的非常非常多,同时单例模式比较容易的一种设计模式. 一.什么是单例设计模式 单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对 ...
- .NET设计模式(1):1.1 单例模式(Singleton Pattern)
概述 单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点. 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单 ...
- java设计模式(四)--单例模式
Singleton最熟悉不过了,下面学习单例模式.转载:http://zz563143188.iteye.com/blog/1847029 单例对象(Singleton)是一种常用的设计模式.在Jav ...
- Java设计模式学习笔记(单例模式)
最近一直在看<Head First设计模式>,这本书写的确实是很不错的,专注于怎么用最简单的方式最通俗的语言让人了解设计模式.据说GoF的设计模式那本书写的很好,是一本经典,但是就是难懂, ...
随机推荐
- 《构建之法》之第8、9、10章读后感 ,以及sprint总结
第8章: 主要介绍了软件需求的类型.利益相关者,获取用户需求分析的常用方法与步骤.竞争性需求分析的框架NABCD,四象限方法以及项目计划和估计的技术. 1.软件需求:人们为了解决现实社会和生活中的各种 ...
- XSS 和 CSRF 攻击
web安全中有很多种攻击手段,除了SQL注入外,比较常见的还有 XSS 和 CSRF等 一.XSS(Cross Site Scripting)跨站脚本 XSS其实就是Html的注入问题,攻击者的输入没 ...
- Java知识点总结(不定时更新)
1.基于分代的垃圾收集算法 设计思路:把对象按照寿命长短来分组,分为年轻代和年老代,新创建的对象被分在年轻代,如果对象经过几次回收后仍然存活,那么再把这个对象划分到年老代.年老代的收集频率不像年轻代那 ...
- 关于foreach中对集合执行Add或者Remove操作引发枚举值被修改异常
方法传入集合List<string> ids; 执行操作后再次循环引发异常 foreach (string id in ids) { ids.Add("a"); } 更 ...
- 通过发布项目到IIS上,登录访问报系统找不到System.Web.Mvc
我发布项目到IIs,通过IIS的端口来访问直接下面的错误
- AI - Ideas
Idea: Comprehend code and re-factory code to more readable. The AI program can comprehend source cod ...
- 利用jquery实现网页禁止鼠标右键、禁止复制
很多时候,网站的内容辛苦写法被轻松复制,为了不让自己的劳动成果外流,可以利用禁止鼠标右键等方式保护自己的原创内容! 方式1:禁止鼠标右键操作 <script src="http://l ...
- 【Effective Java】1、静态工厂的方式代替构造函数
使用一个服提供者对进行服务的提供,服务的请求通过不同的提供者提供不同的服务,服务提供者首先必须在工厂中进行注册,然后才可以通过工厂实例化服务 Service.java package cn.xf.cp ...
- quartz使用(一)
在项目中经常会碰到定时任务,quartz是一款非常优秀的开源框架, 提供了定时任务的支持,还支持任务的持久化,并且提供了对数据库的支持.下面首先对quartz做一个简单介绍,并附上一个小例子. 1.下 ...
- ahjesus 获取当前方法被调用执行的具体位置,包括命名空间和方法
MethodBase method = ).GetMethod(); string ahjesus = method.ReflectedType.FullName + "." + ...