确保一个类只有一个实例
private构造方法、用private static字段持有实例、用public static方法提供访问实例的入口
分类
- 饿汉式:饿怕了,所以先把饭做好
- 懒汉式:懒惯了,所以在需要的时候再做饭
饿汉式
初级饿汉式
类被加载时,就会创建实例。代码中第一次使用Singleton时,该类被加载
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
高级饿汉式:延迟初始化单例模式
用一个静态内部类持有实例,只有在getInstance()时静态内部类才会被加载,才会创建实例
优点:延迟对象的创建(有点像懒汉式),即节省资源
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return InstanceHolder.instance;
}
public static class InstanceHolder {
private static Singleton instance = new Singleton();
}
}
懒汉式
初级懒汉式
实例为空时才创建,但是线程不安全
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
高级懒汉式:双重校验锁单例模式DCL
双重判空,创建实例时加锁,用volatile字段持有实例
优点:在保证线程安全的情况下,将锁最小化以提升性能
public class Singleton {
// volatile在这里起到防止重排序的作用
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
// 第一次线程已经创建了实例,排队等锁的线程进入后要再次判空
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}