本文出自 http://blog.csdn.net/shuangde800
走进单件模式
有些对象我们只需要一个,比如:线程池,缓存,对话框,处理偏好设置和注册表的对象,日志对象,充当打印机,显卡等设备的驱动程序对象等。
这些类的对象只能有一个实例,如果有多个,然而会导致许多问题产生。
有人可能觉得,这只要用全局变量或者静态变量就可以做到了
这样做的缺点:
必须程序一开始就创建对象,但是有些对象可能用不到,耗费资源。而单件模式在需要时才创建
单间模式的实现
单件模式的经典但简陋(有问题)的实现:
把构造函数设置为私有的,再加一个静态方法用来创建对象并返回。
public Singleton{ private static Sigleton uniqueInstance; // 构造器是私有的,只有类内部方法才能创建类 private Singleton() { } public static MyClass getInstance(){ if(uniqueInstance == null){ // 只有是null的才创建对象 uniqueInstance = new Singleton(); } return uniqueInstance; } }
上面那个做法,会出现问题,原因是多线程产生的问题。
假如有两个线程要几乎同时要创建一个对象,那么将会发生下面的情况:
看上图,发现Thread one和Thread two都各自创建了一个对象!
解决方案1:
把getInstance( )变成同步(synchronized)方法,多线程灾难几乎就可以轻易解决了。
public Singleton{ private static Sigleton uniqueInstance; // 构造器是私有的,只有类内部方法才能创建类 private Singleton() { } // 通过增加synchronized关键字,会迫使每个线程在进入这个 // 方法之前,要先等候别的线程离开该方法。 // 也就是说,不会有两个线程可以同时进入这个方法 public static synchronized MyClass getInstance(){ if(uniqueInstance == null){ // 只有是null的才创建对象 uniqueInstance = new Singleton(); } return uniqueInstance; } }
缺点: 每次用该方法都要同步,会降低拖垮程序的性能。同步一个方法可能会造成程序执行效率下降100倍。
解决方案2:急切实例化
public Singleton{ // 在静态初始化器(static initializer)中创建单件 // 保证了线程安全(thread safe) private static Sigleton uniqueInstance = new Singleton(); // 构造器是私有的,只有类内部方法才能创建类 private Singleton() { } public static synchronized MyClass getInstance(){ return uniqueInstance; } }
解决方案3: 用“双重检查加锁”,在getInstance()中减少使用同步
利用“双重检查加锁”(double-checked locking),首先检查实例是否已经创建了,如果尚未创建,“才”进行同步。
这样,只有第一次会同步,之后再也不会了
public Singleton{ // 注意这里加了volatile关键字 // volatile关键字确保:当uniqueInstance变量被初始化成Singleton实例时 // 多个线程正确地处理uniqueInstance变量 private static volatile Sigleton uniqueInstance; private Singleton() { } public static synchronized MyClass getInstance() { if(uniqueInstance == null) { synchronized (Singleton.class) { if(uniqueInstance == null){ uniqueInstance = new Singleton(); } } } return uniqueInstance; } }
注意! 双重检查加锁不使用于java 1.4以及更早的版本。
定义单件模式
单件模式确保一个类只有一个实例,并提供一个全局访问点
单件模式的类图很简单
全局变量 VS 单件模式
在Java中,全局变量基本上就是对对象的静态引用。
在这样的情况下使用全局变量会有一些缺点,我们已经提到了期中一个:急切实例化 VS.延迟实例化。
但是我们要记住这个模式的目的:确保类只有一个实例并提供全局访问。
全局变量也会变相鼓励开发人员,用许多全局变量指向许多小对象来造成命名空间(namespace)的污染。
单件模式不鼓励这样的现象,但单件仍然可能被滥用。
相关推荐
李建忠面向对象设计模式视频精讲:Singleton 单件(创建型模式)
C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式)
C#视频-面向对象设计模式纵横谈(2):Singleton 单件(创建型模式)
C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式) (Level 300)
Head First 设计模式 (五) 单件模式(Singleton pattern) C++实现
36种最新设计模式整理 Design Pattern: Simple Factory 模式 Design Pattern: Abstract Factory 模式 Design Pattern: Builder 模式 Design Pattern: Factory Method 模式 Design Pattern: Prototype 模式 ...
Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)
C++设计模式课件12_Singleton_单件模式.pdf
C#面向对象设计模式纵横谈 第二课 Singleton 单件(创建型模式)
最简单的设计模式学习Singleton模式
C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式) C#面向对象设计模式纵横谈(3):Abstract Factory 抽象工厂模式(创建型模式) C#面向对象设计模式纵横谈(4):Builder 生成器模式(创建型模式) C#面向...
Singleton模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点。这就提出了一个问题:如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?客户程序在调用某一个类时,它是不会考虑这个类是否...
在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要... 这是第2节:创建型模式Singleton单件模式
C#面向对象设计模式纵横谈(2)Singleton 单件(创建型模式)
NULL 博文链接:https://jacky-dai.iteye.com/blog/1927936
设计模式C++学习之单例模式(Singleton)
设计模式-Singleton与Factory
Singleton模式: 确保一个类只有唯一的一个实例。 Singleton主要用于对象的创建,这意味着,如果某个类采用了Singleton模式,则在这个类被创建后,它将有且仅有一个实例可供访问。很多时候我们都会需要Singleton...
3.5 singleton(单件)—对象创建型 模式 84 3.6 创建型模式的讨论 89 第4章 结构型模式 91 4.1 adapter(适配器)—类对象结构型 模式 92 4.2 bridge(桥接)—对象结构型 模式 100 4.3 composite(组成)...