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

应用场景:数据库连接、线程池、缓存、对话框、处理偏好设置、注册表的对象、日志对象、充当打印机、显卡等设备的驱动程序对象、任务管理器、网站的计数器、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. 夏宇闻教授谈FPGA工程师的入门学习

    1. 必须清楚自己究竟适合不适合做工程师. 看看自己的性格特点,是不是特别安静,又耐得住寂寞.因为FPGA工程师是一个辛苦的工作,不但要通过不断学习研究提升自己的设计水平,还要经常性的熬夜加班敲写代码 ...

  2. jQuery中$符号冲突问题 (转载)

    Jquery的$命名冲突: 在Jquery中,$是JQuery的别名,所有使用$的地方也都可以使用JQuery来替换,如$('#msg')等同于JQuery('#msg') 的写法.然而,当我们引入多 ...

  3. C# 文件/文件夹压缩

    一.ZipFile ZipFile类用于选择文件或文件夹进行压缩生成压缩包. 常用属性: 属性 说明 Count 文件数目(注意是在ComitUpdat之后才有) Password 压缩包密码 Siz ...

  4. Android ListView中带有时间数据的排序

    下面是activity: public class MainActivity extends Activity { private ListView mListView = null; private ...

  5. Redhat关闭SELinux和防火墙的办法(转)

    Redhat使用了SELinux来增强安全,关闭的办法为:1. 永久有效修改 /etc/selinux/config 文件中的 SELINUX="" 为 disabled ,然后重 ...

  6. UESTC_王之迷宫 2015 UESTC Training for Search Algorithm & String<Problem A>

    A - 王之迷宫 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  7. iOS 之点击按钮改变状态的图片

    .h  文件中 @property (strong, nonatomic) IBOutletUIButton *publishBtton; @property (strong, nonatomic) ...

  8. Android消息机制不完全解析(上)

        Handler和Message是Android开发者常用的两个API,我一直对于它的内部实现比较好奇,所以用空闲的时间,阅读了一下他们的源码.    相关的Java Class: androi ...

  9. Nginx日志文件配置与切割

    Nginx日志的指令主要有两条: log_format,设置日志的格式 access_log,指定日志文件的存放路径.格式和缓存大小 两条指令在Nginx配置文件中的位置可以在http{……..}之间 ...

  10. Eclipse文件覆盖问题

    window-preferences-General-Search找到第一行的一个选项 Reuse editors to show matches他的意思是说在同一个编辑里面显示匹配的文件,如果后面有 ...