顾名思义,单例模式就是指一个类在内存中只有一个对象 。常见的单例模式:饿汉式,懒汉式,静态内部类,还有一种不常见的利用枚举来实现;
饿汉式:在类加载时就创建好了对象;优点:多线程安全(类加载机制保证),不用加锁效率高;缺点:不管是否用到,该对象都已创建,浪费内存:
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton() {}//构造方法私有化
public static Singleton getInstance() {
return singleton;
}
}
懒汉式:什么时候用到,什么时候创建,涉及线程同步,创建较繁琐,效率偏低:
下面这种写法比较完善:
public class Singleton2 {
private int a = 6;
private static volatile Singleton2 singleton;//禁止指令重排序,否则可能出现半初始化状态对象
private Singleton2() {}
public static Singleton2 getInstance() {
if (singleton == null) {//在这里判空是因为一旦singleton对象创建,再来获取该对象的时候就没有必要走下面的代码来获取锁;双重检查锁定DCL(double-checked locking)
synchronized (Singleton2.class) {
if (singleton == null) {
singleton = new Singleton2();
}
}
}
return singleton;
}
}
静态内部类:通过静态内部类的方式实现单例(懒加载),解决了浪费内存,不涉及线程安全问题,避免申请锁效率低的问题:
public class Singleton3 {
private Singleton3() {}
//外部类加载时,静态内部类不加载,只有内部类被用到时才加载
static class SingleInner {
private static Singleton3 singleton = new Singleton3();
}
public static Singleton3 getInstance() {
return SingleInner.singleton;
}
}
枚举:解决线程同步,还可以防止反序列化(不常见):
public enum Singleton4 {
INSTANCE;
}