public class Singleton {
private Singleton() {}
private static class SingletonHolder{
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
1.为什么是线程安全的
前置知识:类加载时会对静态变量进行初始化,类加载是线程安全的
只有在用到这个类的时候才会触发类的加载,例如:创建类对象,创建子类对象,调用静态方法,调用静态变量,反射创建对象,这几种情况下时jvm会将类加载到方法区。同时外部类加载不会导致内部类加载。
当调用singlentone类的getinstance静态方法时会触发jvm加载sigletone类,静态方法中调用了sigletoneholder类的静态变量,触发jvm加载holder类,同时会初始化instance静态变量,创建tone类对象,由于tone对象创建是在类加载过程中所以是线程安全的
2.为什么满足延迟加载
只有第一次调用tone类的getinstance方法时才会创建instance类对象,因此满足延迟加载。再以后调用方法时由于类已经加载完成,静态变量也已经初始化完成,因此不会再重复执行静态变量初始化操作,以后返回的都是同一个对象
3.是否可以设置为普通内部类
不可以,因为普通内部类不能包含静态变量和静态方法,因此就不能在类加载时进行初始化,会出现线程安全问题
4.为什么holder是private而不是public
因为holder只在stone外部类调用,外部类之外不需要调用因此设置为private