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

  在某些场景,你需要找到一个承担职责的对象,并且这个对象是他所属类的唯一实例。此时可以使用单例模式。

  单例模式的意图是为了确保一个类有且仅有一个实例,并为他提供一个全局的访问点。创建一个担当独一无二角色的对象,有很多方式。但是,不管你如何创建一个单例对象,都必须保证其他开发人员不能创建该单例对象的新的实例。

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

   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。

  对象具有唯一性,并不意味着使用了单例模式。单例模式通过隐藏构造函数,提供对象创建的唯一入口,从而将类的职责集中在类的单例中。

你可能感兴趣的:(Singleton)