在JVM的整个生命周期中,采用单例模式的类,只能有一个实例
(1)不能在类的外部随意调用类的构造器创建实例,因此,私有化构造器(private)
(2)如何在类的外部获得类的实例,提供一个公共方法,由于类的外部不能创建类的实例,因此,该方法必须是类方法(public static SingletonClass getInstance())
(3)在上述公共类方法中返回类的实例,由于静态方法中只能访问静态变量,因此,要返回的类的实例必须是静态变量(static)
(1)懒汉式(线程不安全)
public class SingletonClass { private static SingletonClass instance; private SingletonClass(){ } public static SingletonClass getInstance(){ if(instance == null){ instance = new SingletonClass(); } return instance; } }
(2)懒汉式(线程安全)
public class SingletonClass { private static SingletonClass instance; private SingletonClass(){ } /* public synchronized static SingletonClass getInstance(){ if(instance == null){ instance = new SingletonClass(); } return instance; }*/ public static SingletonClass getInstance(){ synchronized (SingletonClass.class) { if(instance == null){ instance = new SingletonClass(); } } return instance; } }
(3)饿汉式
只要SingletonClass 类被加载了,instance就会被实例化,没有lazy loading
public class SingletonClass { private static SingletonClass instance = new SingletonClass(); private SingletonClass(){ } public static SingletonClass getInstance(){ return instance; } }
public class SingletonClass { private static SingletonClass instance; static{ instance = new SingletonClass(); } private SingletonClass(){ } public static SingletonClass getInstance(){ return instance; } }
(4)采用静态内部类实现lazy loading
SingletonClass 类加载的时候,不会初始化instance,之后真正调用getInstance方法时,才会初始化instance
public class SingletonClass { private static class SingletonHolder{ private final static SingletonClass instance = new SingletonClass(); } public static SingletonClass getInstance(){ return SingletonHolder.instance; } private SingletonClass(){ } }
(5)使用枚举类实现单例模式
public enum SingletonClassEnum{ instance; }
(6)双重校验锁
public class SingletonClass { private volatile static SingletonClass instance; private SingletonClass(){ } public static SingletonClass getInstance(){ if(instance == null){ synchronized (SingletonClass.class) { if(instance == null){ instance = new SingletonClass(); } } } return instance; } }