设计模式-单例(Singleton)模式

来源:互联网 发布:河南科技大学网络认证 编辑:程序博客网 时间:2024/05/17 12:20

单例模式的意图是为了确保一个类有且仅有一个实例,并为它提供一个全局访问点。通过隐藏构造函数,提供对象创建的唯一入口点,从而将类的职责集中在类的单个实例中。

单例模式有几个显著的特点,具体如下所示:

  1. 单例类(Singleton)只能有一个唯一的实例存在。
  2. 单例类必须有能够自行创建自己的实例对象的能力。
  3. 单例类必须能够给外界其他对象提供这个实例。

单例模式机制
创建一个担当着独一无二角色的对象有多种方式。但是,无论你如何创建一个单例对象,都必须确保其他开发人员不能创建该单例对象的新的实例。

为避免其它开发人员实例化自己定义的类,可以创建唯一一个构造函数,并将其设置为私有访问权限。注意,如果创建了其他非私有的构造函数,或者没有创建任何构造函数,其他对象都能够实例化该类。

设计一个单例类事,需要确定何时实例化该类的单例对象。一种做法事创建这个类的实例,并将它作为该类的静态成员变量。例如:SystemStartup类中可能包括这一行:

private static Factory = new Factory();

这个类通过一个公共的getFactory()静态方法获得该类的唯一实例。

如果不希望提前创建单例实例,还可以在第一次需要该实例时,延迟初始化它。例如,SystemStartup类中可能采用如下方式获取单个实例:

public static Factory getFactory(){    if(factory == null)        factory=new Factory();    //...    return factory;}

延迟实例化对象有两个原因:

  1. 在静态初始化时,没有足够的信息对单例对象进行初始化。
  2. 选择延迟初始化单例对象与获取资源有关。例如数据库链接,尤其在一个特定的会话中,它包含的应用程序并不需要该单例对象时。

无论哪种场景,单例模式都建议提供一个公共的静态方法去访问单例对象。如果该方法创建了一个对象,它就要保证只有一个实例可以被创建。

单例和线程

在多线程环境下,无法保证在其他线程开始执行该方法时,当前线程已经完整地执行完该方法。这可能出现两个线程同时初始化一个单例对象地情况。假设第一个线程发现该单例对象为null,紧接着第二个线程运行,也会发现该单例对象为null。然后两个线程都会对该单例对象进行初始化。为了避免这种竞争,需要用锁机制去协调不同线程对同一方法的执行。

package com.oozinoz.bussinessCoreimport java.util.*;public  class Factoy{    private static Factory factory;    private static Object classLock = Factory.class;    private long wipMoves;    private Factory(){        wipMoves = 0;    }    public static Factory getFactory(){        synchronized(classLock){            if(factory == null)                factory = new Factory();            return factory;        }    }    public void recordWipMove(){        synchronized(classLock){            wipMoves++;        }    }

getFactoy()方法保证:当一个线程开始初始化单例的实例时,若另一个线程也开始
相同的操作,则第二个线程就会等待,直到获得classLock对象的锁。而当它获得锁时,会发现该单例不再为null。

以上学习内容参考:
《Java设计模式(第2版)》Steven John Metsker William C.Wake 著
http://www.2cto.com/kf/201504/393325.html

阅读全文
2 0
原创粉丝点击