起因
在此之前,我一直以为单例模式的实现只有两种:懒汉模式和饿汉模式。
具体代码就不写了,无非是饿汉模式在类初始化时就加载,并发安全但浪费资源。懒汉模式在被调用时才加载,虽然节省资源但很容易出现并发问题,通常使用双检锁来提高效率和保证并发安全。
看源码的时候发现单例模式还可以这样实现:
public class Singleton{
private Singleton();
private static class SingletonHolder{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
原理
静态内部类能实现单例模式主要依赖JVM类加载的特性,主要有下面两点:
- JVM在加载外部类的时候并不会加载其静态内部类,在使用到静态内部类的时候才会对静态内部类进行加载。我们知道,类的静态变量是在类加载的时候进行加载的,这样静态内部类实现单例模式就有一个特性:如果没有使用到这个实例,这个实例就不会进行加载。这和懒汉模式一样,能有效节省资源。
- JVM底层保证类加载的安全,即使在高并发的情况下,类的加载都只有一次,这就保证了创建单例时的并发安全性。