java设计模式――单例(Singleton)模式

2014-11-24 00:41:44 · 作者: · 浏览: 0
在某些场景,你需要找到一个承担职责的对象,并且这个对象是他所属类的唯一实例。此时可以使用单例模式。
  单例模式的意图是为了确保一个类有且仅有一个实例,并为他提供一个全局的访问点。创建一个担当独一无二角色的对象,有很多方式。但是,不管你如何创建一个单例对象,都必须保证其他开发人员不能创建该单例对象的新的实例。
  设计一个单例类时,需要确定何时实例化该类的单例对象。一种做法是创建这个类的实例,并将它作为该类的静态成员变量。例如某个类可能包括这一行:
  1 private static Factory factory = new Factory();
  这个类通过一个公共的getFactory()静态方法获得该类的唯一实例。
  如果不希望提前创建单例实例,还可以在第一次需要该实例时,延迟初始化它。
1 public static Factory getFactory() {
2 if (factory == null)
3 factory = new Factory();
4 //.....
5 return factory;
6 }
  
  如果想在一个多线程的环境下初始化一个单例模型,必须小心谨慎地避免多个线程同时初始化该单例对象。在多个线程环境下,无法保证在其他线程开始执行该方法时,当前线程已经完整的执行完该方法。这可能出现两个线程同时初始化一个单例对象的情况。假设第一个线程发现该单例对象为null,第二个线程也发现该单例对象为null,然后两个线程都会对该对象进行初始化。为了避免这种竞争,需要用锁机制去协调不同线程对同一方法的执行。
  java支持多线程开发。它可以为每个对象提供一个锁,用于表示对象是否已经被线程所占用。为确保仅有一个线程初始化单例对象,可以通过对适当的对象进行加锁来同步初始化。其他需要互斥访问单例对象的方法,也可以通过相同的锁机制进行同步。
  
复制代码
1 import java.util.*
2
3 public class Factory {
4 private static Factory factory;
5 private static Object classLock = Factory.class;
6
7 private Factory() {
8 //...
9 }
10
11 public static Factory getFactory() {
12 synchronized (classLock) {
13 if (factory == null)
14 factory = new Factory();
15 return factory;
16 }
17 }
18
19 }
复制代码
  getFactory()方法保证:当一个线程开始初始化单例的实例时,如果另一个线程也开始相同的操作,则第二个线程就会等待,直到获得classLock对象的锁。当它获得锁后,就会发现该单例不再为null。
  对象具有唯一性,并不意味着使用了单例模式。单例模式通过隐藏构造函数,提供对象创建的唯一入口,从而将类的职责集中在类的单例中。