1、饿汉式:类在加载时就创建,如果后面没有用到,会造成资源浪费,不推荐使用。
public class SingleClass { private static SingleClass instance = new SingleClass(); private SingleClass() { } public static SingleClass getInstance(){ return instance; } }
2、懒汉式:类在被加载时不会被初始化,当第一次被使用时进行初始化,为保证单例,可以使用sychronized关键字确保线程安全,但是每次调用时都会同步。
public class LazySingleClass { private static LazySingleClass instance; private LazySingleClass() { } public static synchronized LazySingleClass getInstance(){ if(instance == null){ instance = new LazySingleClass(); } return instance; } }
3、双重检查:当被使用时先判断是否已经初始化,若是则直接返回,若没有,同步初始化。
public class DCLSingleClass { private static DCLSingleClass instance; private DCLSingleClass() { } public static DCLSingleClass getInstance(){ if(null == instance){ synchronized (DCLSingleClass.class){ if(null == instance){ instance = new DCLSingleClass(); } } } return instance; } }
4、静态内部类方法:在类被加载的时候并不会初始化SupperSingleClass,第一次调用getInstance时,初始化SupperSingleClass类,因为被static修饰,JVM只为静态变量分配一次地址空间。
这里有个疑问,JVM在类加载的时候就会为静态变量分配内存吧,那内部类里面的静态成员变量不会在类加载的时候被分配内存吗?
public class SupperSingleClass { private static class InnerClass{ private static final SupperSingleClass instance = new SupperSingleClass(); } private SupperSingleClass() { } public static SupperSingleClass getInstance(){ return InnerClass.instance; } }