序言
单例(Singleton) 是指那些仅仅被初始化一次的类。
如这样
public class Elvis {public static final Elvis INSTANCE = new Elvis();private Elvis() {}public void leaveTheBuilding(){}}
私有的构造器在类被加载的时候,只运行了一次,用来实例化 final 域的 INSTANCE 。(不推荐有安全因素),除此之外还有几种常见的构建单例的方式。
饿汉模式
public class Elvis {private static final Elvis INSTANCE = new Elvis();public static Elvis getINSTANCE() {return INSTANCE;}private Elvis() {}public void leaveTheBuilding() {}}
还可以加入一个 getINSTANCE() 方法,这种方式呢就是之前所说的静态工厂构造, 使用 private static final 则使 INSTANCE 在初始化的时候具有绝对的线程安全。
懒汉的双重加锁机制
public class Elvis {private volatile static Elvis INSTANCE;public static Elvis getINSTANCE() {if (INSTANCE == null) {synchronized (Elvis.class) {if (INSTANCE == null) {INSTANCE = new Elvis();}}}return INSTANCE;}private Elvis() {}public void leaveTheBuilding() {}}
volatile 关键字确保,当 INSTANCE 变量被初始化成Elvis实例时,多个线程正确地处理INSTANCE 变量
静态内部类
public class Elvis {private static class LazyHolder {private static final Elvis INSTANCE = new Elvis();}public static Elvis getINSTANCE() {return LazyHolder.INSTANCE;}private Elvis() {}public void leaveTheBuilding() {}}
序列化问题
上述所有构建单例的方式都有 序列化的问题,因此在实现 Serializable 的同时呢还有加入一个 readResolve方法,否则每一次反序列化都会产生一个新的实例。
private Object readResolve(){return INSTANCE;}
枚举单例
枚举单例就厉害了,无偿提供了序列化机制,绝对防止多次实例化!!!
public class Elvis {enum SingletonEnum {INSTANCE;private Elvis elvis;SingletonEnum() {elvis = new Elvis();}public Elvis getInstnce() {return elvis;}}public static Elvis getINSTANCE() {return SingletonEnum.INSTANCE.getInstnce();}private Elvis() {}public void leaveTheBuilding() {}}
单例枚举已经成为实现单例的最佳方法。
