1、什么是单例?
顾名思义,一个类只有一个实例。(换而言之,就是不能被随便创建实例)
2、如何保证只有一个实例?
将构造方法私有化(构造方法添加 private 修饰符),使其无法使用 new 关键字创建,类自身创建一个实例,提供一个 public 方法,供外部获得该实例。
3、实现代码
法一:最简单方法
优点:简单
缺点:饿汉式加载,在类加载到内存后就会实例化,无法防止反序列化
public class Singleton{
// 初始化一个实例, 使用final必须马上实例化,或者跟随后面用静态代码块实例化
private static final Singleton INSTANCE = new Singleton();
// 将构造方法私有化
private Singleton(){};
// 定义一个获得实例的共有静态方法
public static Singleton getInstance{
return INSTANCE;
}
}
法二:双重锁定
优点:懒汉式加载,lazy loading,实现了类按照实际情况实例化
缺点:使用synchronized加锁,带来了效率下降
public class Singleton{
// 声明一个实例,先不实例化
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;
}
}
法三:静态内部类
完美方案,加载外部类的时候不会加载内部类,所以只在调用getInstance的时候会实例化Singleton()。JVM在加载一个类的时候只加载一次,静态内部类也只会加载一次,保证单例。
public class Singleton(){
// 私有化构造方法
private Singleton(){};
// 定义静态内部类实例化该类
private static class SingletonHolder{
private static final Singleton INSTANCE = new Singleton();
}
// 提供public方法供外部获得实例
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
法四:枚举
完美方案
public enum Singleton{
INSTANCE;
public void whateverMethod(){}
}