单例模式 - OK
单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。
一、单例模式
通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。
单例模式结构图:
Singleton类,定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例。
单例模式示例:

namespace ConsoleApplication1
{
public class Singleton
{
private static Singleton instance; private Singleton() //将构造方法设为private,防止外界利用new创建实例。
{ } public static Singleton GetInstance() //此方法用于获得本类实例的唯一全局访问点
{
if (instance == null) //若实例不存在则new一个新实例,否则返回已有实例
{
instance = new Singleton();
}
return instance;
}
}
class Program
{
static void Main(string[] args)
{
Singleton singleton1 = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance(); //调用静态方法获得实例
if (singleton1 == singleton2)
{
Console.WriteLine("两个对象是相同的实例!"); //输出 两个对象是相同的示例
}
Console.ReadKey();
}
}
}

单例模式与实用类(静态方法)的不同点:
1、实用类不保存状态,仅提供一些静态方法或静态属性让你用,而单例是由状态的。
2、实用类不能用于继承多态,而单例虽然实例唯一,却是可以有子类来继承。
3、实用类只不过是一些方法属性的集合,而单例却是有着唯一的对象实例。
二、多线程时的单例
在上面的例子中,如果是在多线程的程序中,多个线程同时(注意是同时)访问Singleton类,调用GetInstance()方法,会有可能造成创建多个实例的。因此可以通过加lock来处理,lock是确保当一个线程位于代码的临界区,另一个线程不进入临界区。如果其他线程视图进入锁定的代码,则它将一直等待(即被阻止),直到对象被释放。
双重锁定代码示例:

namespace ConsoleApplication1
{
public class Singleton
{
private static Singleton instance;
private static readonly object syncRoot = new object(); private Singleton() //将构造方法设为private,防止外界利用new创建实例。
{ } public static Singleton GetInstance() //此方法用于获得本类实例的唯一全局访问点
{
if (instance == null) //如果实例为空,在外面做一层判断的作用是,当实例不为null时,不用lock,减少资源消耗。
{
lock (syncRoot) //锁定
{
if (instance == null) //当两个线程同时调用GetInstance()时,他们都可以通过第一重instance=null的判断,然后由于lock机制,
//这两个线程只有一个进入,另一个等候,如果没有第二重的instance=null的判断,则第一个线程创建了实例,第二个线程由于过了第一重instance=null,
//因此在没有第二重instance == null判断的情况下还是会创建实例。
{
instance = new Singleton();
}
}
}
return instance;
}
}
class Program
{
static void Main(string[] args)
{
Singleton singleton1 = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance(); //调用静态方法获得实例
if (singleton1 == singleton2)
{
Console.WriteLine("两个对象是相同的实例!"); //输出 两个对象是相同的示例
}
Console.ReadKey();
}
}
}

三、静态初始化
其实在实际应用中,C#与公共语言运行库也提供了一种‘静态初始化’方法,这种方法不需要开发人员显式地编写线程安全代码,既可解决多线程环境下它是不安全的问题。相对于上面的来说,两种方法都可以达到相同的单例目的,只是实现更加简单而已,来看下实现代码:

namespace ConsoleApplication1
{
public sealed class Singleton //注意必须设置为密封类
{
private static readonly Singleton instance = new Singleton(); //注意声明为只读
private Singleton()
{ }
public static Singleton GetInstance()
{
return instance;
}
}
class Program
{
static void Main(string[] args)
{
Singleton singleton1 = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance(); //调用静态方法获得实例
if (singleton1 == singleton2)
{
Console.WriteLine("两个对象是相同的实例!"); //输出 两个对象是相同的示例
}
Console.ReadKey();
}
}
}

这种实现与前面的示例类似,也是解决了单例模式试图解决的两个基本问题:全局访问和实例化控制,公共静态属性为访问实例提供了一个全局访问点。不同之处在于它依赖公共语言运行库来初始化变量。由于构造方法是私有的,因此不能在类本身以外实例化Singleton类;因此,变量引用的是可以再系统中存在的唯一实例。不过要注意,instance变量标记为readonly,这意味着只能在静态初始化期间或在类的构造函数中分配变量。由于这种静态初始化的方式是在自己被加载时就将自己实例化,所以被形象地称之为饿汉单例模式。而上面的第二种是在第一次被引用的时候,才会将自己实例化,所以就被称之为懒汉单例模式。
由于饿汉式,即静态初始化的方式,它是类一加载就实例化对象,所以要提前占用系统资源。然而懒汉式,又会面临着多线程访问的安全性问题,需要做双重锁定这样的处理才可以保证安全。所以到底使用哪一种方式取决于实际的需求。从C#语言的角度来讲,饿汉式的单例模式已经足够满足我们的需求。
单例模式 - OK的更多相关文章
- 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.单例类必须自己创建 ...
随机推荐
- 【转】Android:ListView常见错位之CheckBox错位
原文网址:http://blog.csdn.net/lemon_tree12138/article/details/39337867 ListView在什么样的情况下会出现错位?错位的原因是什么?怎么 ...
- 易pc,1G容量以上的u盘,另外还要一台装了windows系统的电脑。
一.硬件:易pc,1G容量以上的u盘,另外还要一台装了windows系统的电脑. 二.软件: 1.windows xp的安装包.考虑到易PC的硬盘容量,还是用精简版的吧,比如“Deepin XP Li ...
- 你应该了解的 7个Linux ls 命令技巧
在前面我们系列报道的两篇文章中,我们已经涵盖了关于‘ls’命令的绝大多数内容.本文时‘ls命令’系列的最后一部分.如果你还没有读过该系列的其它两篇文章,你可以访问下面的链接. 15 个‘ls’命令的面 ...
- 微信中web页面实现和公众号中查看图片一样的效果
最近开发了一套资讯相关的web页面,嵌套在微信中,可支持点赞.评论等...在文章详情中,图片需要点击放大,随手势放大缩小,左右可滑动切换,总之类似于微信公众号效果. 开始想的方案是用轮播插件.或者在i ...
- HDOJ 5093 Battle ships 二分图匹配
二分图匹配: 分别按行和列把图展开.hungary二分图匹配. ... 例子: 4 4 *ooo o### **#* ooo* 按行展开. .. . *ooo o#oo oo#o ooo# **#o ...
- 路由器WAN口和LAN口详解
前一阵子做路由器的联网,由于利用了Openwrt操作系统,做起来虽然方便,但是很多原理细节都被忽略了.所以这里再来老生常谈一下wan口和lan口的区别,以及他们之间的工作原理. 首先百度一下,基本知识 ...
- linux系统自动执行任务(转)
开机启动 开机启动应该是我们很经常的需求了,我们常需要在开机时就自动执行某些命令来开启服务,进程等,有了它我们不必再在每次开机时输入同一堆命令. chkconfig命令 使用chkconfig命令可以 ...
- JAVA内存区域和GC机制
目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...
- Java 8十个lambda表达式案例
1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnable() { @Override public ...
- django: form fileupload - 1
本节介绍 Form 中一些字段类型的使用,以文件上传字段 FileField 为例:(注,其它字段和相关用法见官方文档中的 Forms -> Built-in Fields) 一,配置 urls ...