“Head First 设计模式“ :单例模式

单例模式


定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。类图如下:

“Head First 设计模式“ :单例模式


代码实现如下:

public class Singleton {
    // 用静态变量来记录唯一的实例
    private static Singleton instance;
    /**
     * 构造方法私有化,防止被创建,只能类内部能使用构造器
     */
    private Singleton() { }
    /**
     * 实例化对象,并返回这个对象
     * @return
     */
    public static Singleton getInstance() {
        if (instance == null) {
                instance = new Singleton();
        }
        return instance;
    }
    // 其他的方法
}

并发环境下上面的代码会出现问题的,我们进一步修改,如下:

/**
 * 实例化对象,并返回这个对象
 * synchronized加锁,可能对性能有影响哦
 * @return
 */
public static synchronized SingletonThread getInstance() {
    if (instance == null) {
                instance = new SingletonThread();
    }
    return instance;
}

上面例子对性能很大的影响,那我们可以进一步改善吗?


  1. 如果getInstance()的性能对应用程序不是很关键,就什么都别做,不要改善了

  1. 使用“急切”创建实例,而不用延迟实例化的做法,代码如下:
public class Singleton3 {
  // 静态属性,类加载时初始化的,JVM保证唯一
  private static Singleton3 instance = new Singleton3();
    private Singleton3() { }
    public static Singleton3 getInstance() {
        return instance;
    }
}

  1. 使用“双重检查加锁”,在getInstance()中减少使用同步,不适合JDK1.4之前的版本,代码如下;
public class Singleton4 {
  // 用静态变量来记录唯一的实例, volatile多线程环境下保用最新的值
  private volatile static Singleton4 instance;
    /**
     * 构造方法私有化,防止被创建,只能类内部能使用构造器
     */
    private Singleton4() {
    }
    /**
     * 实例化对象,并返回这个对象
     * @return
     */
    public static Singleton4 getInstance() {
        if (instance == null) {
            synchronized (Singleton4.class) {
                if (instance == null) {
                    instance = new Singleton4();
                }
            }
        }
        return instance;
    }
    // 其他的方法
}

注意:有多个类加载器时,单利可能产生多个哦,这个要注意哦。

单例模式的应用场景:

  • 应用中某个实例对象需要频繁的被访问。
  • 应用中每次启动只会存在一个实例。如账号系统,数据库系统。