SINGLETON(单例模式)—对象创建型模式
单例其实就是唯一实例的意思,也就是说一个类只能有一个实例。开发人员都知道,在Java中,只要new一个类,就会创建这个类的实例,如果把这个类new多次,就会创建这个类的多个实例。有时候如果在程序运行时,不管new多少次,只需要这个类的一个实例,如日志记录中的管理类,要怎么处理呢?这是就需要用到单例模式。
1. 问题
那么怎样来确保一个特殊类的实例是独一无二的(它是这个类的唯一实例),并且这个实例易于被访问呢?
2. 解决方案
1)全局变量:一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象。因为你的任何代码都能修改全局变量,这将不可避免的引起更多调试的意外。换句话说,全局变量的状态总是会出现一些问题的。
2)类构造函数私有和类自身的静态方法:让类自身负责保存它的唯一实例(静态变量)。这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求) ,并且它可以提供一个访问该实例的方法(静态方法)。这就是Singleton模式。
3. 适用性2)当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
4. 实现:
单例模式的示意图UML结构:
单例模式的示意图
//饿汉式单例模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton(){ //.... } public static Singleton getInstance(){ return instance; } }
//懒汉式单例模式 public class Singleton { private static Singleton instance = null; private Singleton(){ //.... } public static Singleton getInstance(){ if(instance == null) { instance = new Singleton(); } return instance; } }上述的懒汉式单例模式在单线程中没有任何问题,但是在多线程中就会出问题。此时可以增加syschronized(同步)机制
public class Singleton { private static Singleton instance = null; private Singleton(){ //.... } public static <strong>synchronized </strong>Singleton getInstance(){ if(instance == null) { instance = new Singleton(); } return instance; } }而这种效果比较低,可以将syschronized放在产生实例的前面
public class Singleton { private static Singleton instance = null; private Singleton(){ //.... } public static Singleton getInstance(){ if(instance == null) { <strong>synchronized(Singleton.class)</strong>{ instance = new Singleton(); <span style="white-space: pre;"> </span>} } return instance; } }这种写法避免了每次获取实例时,都进入syschronized(同步)机制,但是和最初的写法一样,采用这种写法则避免不了在多线程时,返回多个实例的问题,因此使用Double-checked locking(双检测锁)机制,示例代码如下:
public class Singleton { private static Singleton instance = null; private Singleton(){ //.... } public static Singleton getInstance(){ if(instance == null) { synchronized(Singleton.class){ if(instance==null){ instance = new Singleton(); } } } return instance; } }
5. 效果
Singleton模式有许多优点:
1) 对唯一实例的受控访问, 因为Singleton类封装它的唯一实例,所以它可以严格的控制客户怎样以及何时访问它。
2) 缩小名空间,Singleton模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染名空间。
3) 允许对操作和表示的精化Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。你可以用你所需要的类的实例在运行时刻配置应用。
4) 允许可变数目的实例 这个模式使得你易于改变你的想法,并允许Singleton类的多个实例。此外,你可以用相同的方法来控 制应用所使用的实例的数目。只有允许访问 Singleton实例的操作需要改变。
原文地址:http://blog.csdn.net/dream_angel_z/article/details/45243851