一、单例模式简介

单例模式是为保证一个对象,在程序运行的任何时刻只有一个实例存在,我们把这种实现方式称之为“单例模式”。

二、单例模式的核心

单例类只有一个实例存在

单例类提供一个全局访问点

单例类通过自己创建唯一实例

单例类对外所有访问对象都提供一个唯一实例。

三、单例模式的优点

1、在程序运行中只有一个实例,减少内存占用,减少频繁的创建和销毁实例所带来的系统开销,

2、避免资源的多种无效占用

单例模式缺点:

没有接口 不能继承

四、单例模式应用场景

当一个事物在特定的环境中,只会存在一个实例时,我们可以采用单例模式对其进行设计。

例: 数据库连接池,计算机注册表 一个国家只有一个总统 日志系统中的日志文件 计算机中的打印池 计算机设备管理器

生成唯一序列号 网站计数器

五、单例模式的实现方式

1、非线程安全(尽量不要用)

public sealed class Singleton

{

private static Singleton instance=null;

private Singleton()

{

}

public static Singleton Instance

{

get

{

if (instance==null)

{

instance = new Singleton();

}

return instance;

}

}

}

说明:上面的方法是非线程安全的,2个不同的线程可以同时进入这个方法,如果instance为空的并且这里返回真的情况下,都可以创建实例,这显然违反了单例模式,实际上,在测试以前,实例就已经有可能被创建了,

但是内存模型不能保证这个实例能被其他的线程看到,除非合适的内存屏障已经被跨过了。

2、简单的线程安全

public sealed class Singleton

{

private static Singleton instance = null;

private static readonly object padlock = new object();

Singleton()

{

}

public static Singleton Instance

{

get

{

lock (padlock)

{

if (instance == null)

{

instance = new Singleton();

}

return instance;

}

}

}

}

上述实现是线程安全的。这个线程在共享的object上取出了一把锁,然后在创建实例以前检查这个实例是否被创建了。

这个保护了内存屏障问题(lock保证了所有的读取操作是在LOCK获得以后发生的,所有的unlock保证了所有的写操作在lock 释放以后发生的),这样就保证了一个线程只能创建一个实例(每次只有一个线程在这段代码中运行),不巧的是,性能上来说,锁变成了每次都必须的当这个实例被响应的时候。

3、尝试线程安全(双重锁定)不推荐使用

public sealed class Singleton

{

private static Singleton instance = null;

private static readonly object padlock = new object();

Singleton()

{

}

public static Singleton Instance

{

get

{

if (instance == null)

{

lock (padlock)

{

if (instance == null)

{

instance = new Singleton();

}

}

}

return instance;

}

}

}

4、不完全lazy,但是线程安全且不用用锁 推荐使用

public sealed class Singleton

{

private static readonly Singleton instance = new Singleton();

// 显示的static 构造函数

//没必要标记类型 - 在field初始化以前

static Singleton()

{

}

private Singleton()

{

}

public static Singleton Instance

{

get

{

return instance;

}

}

}

欢迎关注我的公众号(同步更新文章)DoNet技术分享平台

阅读原文

C#开发模式——单例模式的更多相关文章

  1. 【python之路33】开发模式单例模式及简单的服务器请求框架原理

    1.单例模式指的是创建单个实例,例如:数据库连接池中包含10个数据库连接,用户访问数据时随机从连接池中拿出一个进行连接,其他用户再次访问时不再创建对象进行连接 #!usr/bin/env python ...

  2. Aoite 系列(04) - 强劲的 CommandModel 开发模式(上篇)

    Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案.Aoite.CommandModel 是一种开发模式,我把它成为"命令模型",这是一 ...

  3. js开发模式

    js中的开发模式进化史: js中有最初的只能由基本数据类型描述——>单例模式-->工厂模式-->构造函数模式-->原型模式-->各个模式相结合的混合模式,下面我会给大家逐 ...

  4. webpack+react+redux+es6开发模式

    一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...

  5. 企业应用开发模式 ERP项目中应用到的技术和工具

    一.基础技术选型 C# .NET 3.5/4.0  这两个版本的.NET已经相当方便(Linq, Lambda,Parallel),语法简洁,配合WCF和WF两项技术,可以满足快速开发,维护方便的目标 ...

  6. webpack+react+es6开发模式

    一.前言 实习了两个月,把在公司用到的前端开发模式做个简单的整理.公司里前端开发模式webpack+react+redux+es6,这里去掉了redux. webpack, react, redux等 ...

  7. 一种开发模式:ajax + ashx + UserControl

    一.ajax+ashx模式的缺点     在web开发过程中,为了提高网站的用户体验,或多或少都会用到ajax技术,甚至有的网站全部采用ajax来实现,大量使用ajax在增强用户体验的同时会带来一些负 ...

  8. ASP.NET MVC——CodeFirst开发模式

    Entity Framework框架提供了几种开发模式,比如Database First,Model First,Code First.Database First是最老也是应用得最广泛的一种设计方式 ...

  9. java 开发模式

    Java-开发模式 Java Web开发方案有多种,这里列举一些经典的开发模式进行横向比较JSP+JAVABEAN开发模式:    特点:该模式将业务逻辑与页面表现进行分离,在一定程度上增加了程序的可 ...

随机推荐

  1. android 模拟器对应键盘快捷键

    一位同事的总结资料: Android SDK2.0.1自带的虚拟机尺寸都比较小(不针对机型,只为了在PC上看的舒服一点,当然越大越好了,我最大设置成1050*450,但是自带的屏保会不够宽,900*4 ...

  2. robot framework环境搭建

    来源:http://www.cnblogs.com/puresoul/p/3854963.html[转] 一. robot framework环境搭建: 官网:http://robotframewor ...

  3. Vulkan Tutorial 14 Integration pipeline

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 我们现在整合前几章节的结构体和对象创建图形管线!以下是我们现在用到的对象类型,作为一 ...

  4. Spring学习(19)--- Schema-based AOP(基于配置的AOP实现) --- 配置切面aspect

    Spring所有的切面和通知器都必须放在一个<aop:config>内(可以配置包含多个<aop:config>元素),每个<aop:config>包含pointc ...

  5. Ubuntu安装搜狗拼音和金山快盘

    搜狗拼音和金山快盘是UbuntuKylin中的特色中文应用,通过下述方法在Ubuntu或UbuntuKylin中安装. 一.更新Fcitx 1.由于 Ubuntu 12.04自带的 小企鹅输入法Fci ...

  6. go 测试sort性能

    package main import "fmt" import "os" import "flag" import "bufio ...

  7. python str转dict

    两种方法 捷径 eval(str) >>> user = "{'name' : 'jim', 'sex' : 'male', 'age': 18}" >&g ...

  8. Navicat连接Oracle报错_Cannot load OCI DLL 87

    原因: Oracle需要装client才能让第三方工具通过OCI(Oracle Call Interface)来连接. 解决方案: 1. 去oracle官网下载Instant Client 11, 或 ...

  9. Java IO学习笔记一

    Java IO学习笔记一 File File是文件和目录路径名的抽象表示形式,总的来说就是java创建删除文件目录的一个类库,但是作用不仅仅于此,详细见官方文档 构造函数 File(File pare ...

  10. 浅谈OpenStack架构

    首先,先来了解,什么是OpenStack?   OpenStack是一个云平台管理的项目,它不是一个软件.这个项目由几个主要的组件组合起来完成一些具体的工作.OpenStack是一个旨在为公共及私有云 ...