参考《Head First 设计模式》
单件模式 定义:确保一个类只有一个实例,并提供一个全局的访问点。
单件模式如果没有做同步处理,在多线程环境下很容易造成出现多个实例情况。一下三种实现方式可以解决这个问题。
实现一:
public class Singleton { private static Singleton uniqueInstance; // other useful instance variables here private Singleton() {} public static synchronized Singleton getInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } // other useful methods here }
此方法是好理解的一种,但是有个缺陷,在每次调用getInstance()方法都需要进行代码同步,所以代码执行效率会有所降低。还有单例模式在创建实例后就不需要进行同步处理了,如果在调用程序频繁且对性能要求较高的地方尽量少使用此方法。
实现二(急切创建实例):
public class Singleton { private static Singleton uniqueInstance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return uniqueInstance; } }
利用这种做法,JVM在加载这个类是就马上创建此唯一的单件实例。JVM保证在任何线程访问uniqueInstance变量之前,一定先创建此实例。在静态初始化器中创建单件,保证了线程安全。
如果程序总是创建并使用单件实例,或者在创建和运行时方面的负担不太繁重,可以考虑此方法。
实现三(双重检查加锁):
public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() {} public static Singleton getInstance() { if (uniqueInstance == null) { synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }
首先检查是否创建实例了,如果未创建才进行同步。这样一来,只有第一次才会进行同步。第一次执行时。进入同步代码块后在检查一次,这样做确保多个线程执行时,创建唯一实例。如果仍是null,才创建实例。
注意此处用到volatile 修饰符,确保变量uniqueInstance被初始化成Singleton实例时,多个线程立即可见
。