保证一个类仅有一个实例,并提供一个访问它的全局访问点。——DP

UML类图

模式说明

个人认为单例模式是所有设计模式中最为简单的一个模式,因为实现这个模式仅需一个类,而不像其他模式需要若干个类。这个模式中,需要注意的一点就是获取实例时的线程安全问题。

通常单例模式的实现方式如下:

   class ToolBox
{
// 阻止外部实例化ToolBox
private ToolBox()
{
guid = Guid.NewGuid();
} private static ToolBox instance;
private static object lockObj = new object(); //提供一个全局访问点
public static ToolBox GetToolBoxInstance()
{
if (instance != null) return instance; //要考虑线程安全问题
lock (lockObj)
{
if (instance == null)
{
instance = new ToolBox();
}
} return instance;
} #region 用于测试 private Guid guid; public void ShowGuid()
{
Console.WriteLine(guid.ToString());
} #endregion }

另外,C#语言中提供一种“静态初始化”功能,对静态初始化器的调用是由CLR控制的,并且CLR会解决线程安全问题,保证只调用一次。所以也可以利用这个特性,来简化单例模式的C#实现:

    class ToolBox2
{
// 阻止外部实例化ToolBox2
private ToolBox2() { guid = Guid.NewGuid(); } //静态内联初始化
private static readonly ToolBox2 instance = new ToolBox2(); //提供一个全局访问点
public static ToolBox2 GetToolBoxInstance()
{
return instance;
} #region 用于测试 private Guid guid; public void ShowGuid()
{
Console.WriteLine(guid.ToString());
} #endregion
}

客户端访问代码如下(从输出可以看到,每次访问获取的都是同一个实例):

        static void Main(string[] args)
{
// 测试单例模式
for (int i = ; i < ; i++)
{
new Thread(x =>
ToolBox.GetToolBoxInstance().ShowGuid()
).Start();
} Thread.Sleep();
Console.WriteLine(); // 测试单例模式
for (int i = ; i < ; i++)
{
new Thread(x =>
ToolBox2.GetToolBoxInstance().ShowGuid()
).Start();
} /* 输出如下
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5
f38db210-20bc-4c2d-8d43-40a0e58fedd5 8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
8398be29-abd3-4abd-abf8-4fd09641427c
*/ Console.ReadKey();
}

总结

单例模式和前面介绍的工厂模式(工厂方法、抽象工厂)都属于创建型模式,负责类的实例化过程。单例模式的实现过程,只需要一个类,算是最简单的一个模式,在多线程环境下,单例模式的实现必须保证线程安全,否则在多个线程同时访问时,可能产生多个实例。在C#中,可以通过语言本身的特性(静态初始化器)来更简洁地实现单例模式。

参考

  1. 程杰老师  《大话设计模式》

设计模式——单例模式(Singleton)的更多相关文章

  1. 设计模式 单例模式(Singleton) [ 转载2 ]

    设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...

  2. 设计模式 单例模式(Singleton) [ 转载 ]

    设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...

  3. JAVA设计模式-单例模式(Singleton)线程安全与效率

    一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...

  4. 浅谈设计模式--单例模式(Singleton Pattern)

    题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...

  5. [工作中的设计模式]单例模式singleton

    一.模式解析: 单例模式是最简单和最常用的设计模式,面试的时候,不管新毕业的学生还是已经工作多年的筒子,对单例模式基本都能聊上两句.单例模式主要体现在如下方面: 1.类的构造函数私有化,保证外部不能直 ...

  6. 23种设计模式--单例模式-Singleton

    一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...

  7. 设计模式--单例模式Singleton(创建型)

    单例模式很显然是定义一个类,这个类在程序中只有唯一的实例对象.一般单例类的构造函数是私有的,只能通过调用静态函数GetInstance来获取实例. 一.单例模式有三种:懒汉式单例.饿汉式单例.登记式单 ...

  8. 设计模式--单例模式Singleton

    单例模式顾名思义整个程序下只有一个实例,例如一个国家只有一个皇帝,一个军队只有一个将军.单例模式的书写又分为饿汉模式和懒汉模式 饿汉模式   类中代码 package demo; public cla ...

  9. 设计模式-单例模式(Singleton) (创建型模式)

    //以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Singleton.h #pragma once #include<iostream> class Sin ...

随机推荐

  1. bzoj 4044: Virus synthesis 回文自动机

    题目大意: 你要用ATGC四个字母用两种操作拼出给定的串: 将其中一个字符放在已有串开头或者结尾 将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空.求最少操作次数. le ...

  2. 洛谷 P1379 八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了 ...

  3. 【转】 Pro Android学习笔记(六八):HTTP服务(2):HTTP POST

    目录(?)[-] 找一个测试网站 HTTP POST小例子 上次学习了HTTP GET请求,这次学习一下HTTP POST. 找一个测试网站 小例子好写,但要找个测试网站就有些麻烦,一下子无从入手,都 ...

  4. 集群重启某一主机下所有osd down解决办法

    标签(空格分隔): ceph 运维 osd 问题描述: 掉电后,上电发现cluster中的主机node3下的所有osd都down掉了,通过命令重启node3的ceph-osd服务,osd依然无法up: ...

  5. 第三波精品Android源码袭来!免费下载

    今天又汇总了一些源码供大家免费下载学习! 1.Android实现NewQuickAction快捷菜单NewQuickAction能根据点击事件发生的坐标来显示一个快捷菜单,比如点击位置在靠近底部,则弹 ...

  6. MySql数据查询的逻辑蕴含条件问题

    SQL语言中没有蕴含逻辑运算.但是,可以利用谓词演算将一个逻辑蕴含的谓词等价转换为:p->q ≡┐p∨q. 我们通过一个具体的题目来分析:(具体的表和数据详见文章:Mysql数据库中的EXIST ...

  7. Material使用05 MdListModule模块 MdButtonToggleModule模块

    1 在共享模块中导入MdListModule模块 import { NgModule } from '@angular/core'; import { CommonModule } from '@an ...

  8. 笔试题: 数据库 已看1 一些关键的sql语句练习 和选择题 有用 sql语句练习 挺好

    一.     选择题 1.SQL语言是( C )语言. A.层次数据库 B.网络数据库 C.关系数据库 D.非数据库     redis 是 3.如果在where子句中有两个条件要同时满足,应该用哪个 ...

  9. 17、SAM文件格式说明(转载迷宫中的将军)

    1. SAM格式说明 SAM代表Sequence Alignment/Map格式,是一种制表符分隔的文本格式,包含一个可选的头部分(header section,有人称之为“注释部分”),和一个比对部 ...

  10. 存储引擎InnoDB

    InnoDB是MySQL的默认存储引擎, InnoDB支持的最大存储限制是64TB,支持事务安全,支持行锁,支持B树索引,不支持哈希索引和全文索引,支持集群索引,支持数据缓存,支持索引缓存,不支持数据 ...