单例模式:确保一个类只有一个实例,并提供一个全局访问点。

应用场景:数据库连接、线程池、缓存、对话框、处理偏好设置、注册表的对象、日志对象、充当打印机、显卡等设备的驱动程序对象、任务管理器、网站的计数器、Web应用的配置对象的读取、操作系统的文件系统。

几种实现方法代码:

(1)简单的实现(惰性实例化)

public sealed class Singleton
{
private Singleton() { } private static Singleton instance = null; public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}

简单实现对于线程来说是不安全的,因为在多线程的情况下,有可能产生多个Singleton实例。多线程的情况下,如果多个线程都去判断(instance == null),而它们都还没有创建实例的情况下,就会产生多个Singleton实例。对于简单实现来讲,Singleton实例化并不是应用程序启动就创建,所以我们把它叫做“惰性实例化”,这能避免应用程序启动时实例化不必要的实例。

(2)线程安全的实现

public sealed class Singleton
{
private Singleton() { } private static Singleton instance = null;
private static readonly object padLock = new object(); public static Singleton Instance
{
get
{
lock (padLock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
}

安全的线程,这是对简单实例的补充。因为提供了加锁lock()的操作,这就能确保只有一个线程进入。但是加锁需要增加额外的开销,损失性能。

(3)双重锁定检查

public sealed class Singleton
{
public Singleton() { } private static Singleton instance = null;
private static readonly object padLock = new object(); public static Singleton Instance
{
get
{
if (instance == null)
{
lock (padLock)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}

双重锁定检查安全的线程上面又进行了改进,主要是考虑了每次加锁会增加额外的开销,影响性能。所以在加锁前再判断Singleton有没有被实例化。这样,它就能减少很多的额外开销且是线程安全的。实际上,应用程序很少需要上面方式的实现。这种方式仍然有很多缺点:无法实现延迟初始化。大多数情况下我们会使用静态初始化的方式。

(4)静态初始化

public sealed class Singleton
{
static readonly Singleton instance = new Singleton(); private Singleton() { } public static Singleton Instance
{
get
{
return instance;
}
}
}

静态初始化,是在 .NET 中实现 Singleton 的首选方法。

(5)延迟初始化

public sealed class Singleton
{
public Singleton() { } public static Singleton Instance
{
get
{
return Delay.DelayInstance;
}
}
} public sealed class Delay
{
private static readonly Singleton delayInstance = new Singleton();
private Delay() { } public static Singleton DelayInstance
{
get
{
return delayInstance;
}
}
}

把实例化的工作交给Delay类开实现,这样Singleton类就实现了延迟初始化。这种方式具有很多的优势,是值得推荐的一种实现方式。但是这种方式就需要开发人员记住不能使用new关键字实例化Singleton。

HeadFirst设计模式读书笔记(5)-单例模式的更多相关文章

  1. HeadFirst设计模式读书笔记--目录

    HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...

  2. HeadFirst设计模式读书笔记之工厂模式

    1. 简单工厂 1. 你开了一家披萨店,点披萨的方法可能是这样: public Pizza orderPizza(String type) { Pizza pizza; if (type.equals ...

  3. HeadFirst设计模式读书笔记(4)-工厂模式

    工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个.工厂方法让类把实例化推迟到子类. 所有工厂模式都用来封装对象的创建.工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象 ...

  4. HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)

    装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...

  5. HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern)

    观察者模式:定义了对象之间一对多的依赖关系,这样一来,当一个对象的状态发生改变时,它的依赖者将会受到通知并且自动更新. 有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事,对象甚至在运行时可以 ...

  6. HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)

    策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...

  7. HeadFirst设计模式读书笔记之策略模式

    1. 例子 1. 做一个鸭子模拟器,里面有很多不同的鸭子,有的可以游泳,有的可以睡觉,有的可以呱呱叫,一般套路是定义一个鸭子的超类,在 超类里定义睡觉,游泳,呱呱叫的方法,再让不同的鸭子子类继承这个超 ...

  8. Java设计模式学习笔记(五) 单例模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 使用单例模式的原因 以Windows任务管理器为例,在Windows系统中,任务管理器是唯 ...

  9. Delphi 设计模式:《HeadFirst设计模式》Delphi2007代码---单例模式之ChocolateBoiler[转]

     1  2{<HeadFirst设计模式>之单例模式 }  3{ 编译工具: Delphi2007 for win32 }  4{ E-Mail : guzh-0417@163.com   ...

随机推荐

  1. STM32工程中出现 error: A1163E: Unknown opcode R0, , expecting opcode or Macro错误分析及处理

    最近测试以前的一个程序,一般都是打开以前写的程序修改参数直接测试 但是发现以前的编译后出现错误. 奇怪了,以前的出现都是调试好了的啊,一般都是没有错误的,迅速找问题 跳转到错误代码行 代码区域 Hea ...

  2. tk资料

    Hello World: 让我们开始,作为其他教程的开始, 以"Hello World"程序创建一个文件 叫做Hello.pl  键入下面的内容到它这里: #!/usr/local ...

  3. 剑指offer-面试题14.调整数组顺序使奇数位于偶数的前面

    题目:输入一个整数数组,实现一个函数来调整该数组中的数字的顺序, 使得所有的奇数位于数组的前半部门,所有的偶数位于数组的后半部门. 这一题一看其实是很简单的,当然在不考虑效率的情况可以这样考虑 我们将 ...

  4. PHP 表单验证 - 必填字段

    -------------------------------------------------------------------------- 本节展示如何制作必填输入字段,并创建需要时所用的错 ...

  5. HBase的基本操作

    1.输入hbase shell进入HBase shell

  6. c语言的lua库编写

    gcc编译 gcc -I/usr/local/include/ -L/usr/local/lib/ -lm -o engine_mlisten_lua ./src/engine_mlisten_lua ...

  7. Java中对象的三种状态

    Java中的对象的三种状态是和垃圾回收紧密相关的,因此有必要深究. 状态一:可触及态:从根节点开始,可以搜索到这个对象,也就是可以访问到这个对象,也有人将其称为可达状态. 状态二:可复活态:从根节点开 ...

  8. 第五章 Logistic回归

    第五章 Logistic回归 假设现在有一些数据点,我们利用一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称作回归. 为了实现Logistic回归分类器,我们可以在每个特征上都乘以一 ...

  9. [KMP求最小循环节][HDU3746][Cyclic Nacklace]

    题意 给你个字符串,问在字符串末尾还要添加几个字符,使得字符串循环2次以上. 解法 无论这个串是不是循环串 i-next[i] 都能求出它的最小循环节 代码: /* 思路:kmp+字符串的最小循环节问 ...

  10. hibernate某些版本(4.3)下报错 NoSuchMethodError: javax.persistence.Table.indexes()

    其实本来没啥大问题,但到网上查的时候发现了一些误人子弟的说法,所以还是记下来吧. 现象: hibernate从低版本升级到某一个版本时(我们是升到4.3.10)时,在程序启动时会报错: java.la ...