单列模式:创建型设计模式,涉及如何创建对象,单列模式的核心思想就是,无论该类使用多少次,都只产生一个该类对象,可以减少系统内存的消耗
单列模式的第一步:创建本类的私有方法
-
立即加载的单列模式:在类加载时,直接实例化对象,以后都返回该对象的引用
缺点:在类初始化时进行加载,也会浪费内存
优点:没有加锁,执行效率高,是线程安全的实例
public class Singleton { //立即加载的单列模式 //类加载时,直接实例化,以后都返回该对象的引用 private Singleton(){//私有构造 } //私有静态属性 private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; }
-
延迟加载的单列模式:延迟加载——懒汉模式,类加载的时候不实例化,而是调用方法时,再实例化
优点:不占内存
缺点:在单线程模式下是安全的,多线程模式下,多个线程同时执行instance==null则会创建多个实例
解决方案1:在getInstance()加上synchronized上锁,虽然保障了线程安全,但锁的范围太大了,效率低
解决方案2:双重检验模式,只会在第一次的效率变慢,实例被创建之后,其他线程可以获取instance不为空,就不会再
//延迟加载单列模式 //类加载的时候不完成实例化,调用方法时才完成实例化 //线程安全的懒汉模式 private LazySingleton(){} private static volatile LazySingleton instance; public static LazySingleton getInstance(){ if (instance==null) { synchronized (LazySingleton.class){//双重检验,适用多线程 if (instance==null){ instance =new LazySingleton(); } } } return instance; }
//线程不安全延迟加载单列模式 //类加载的时候不完成实例化,调用方法时才完成实例化 //多线程时容易出异常 private LazySingleton(){} private static volatile LazySingleton instance; public static LazySingleton getInstance(){ if (instance==null) { instance =new LazySingleton(); } return instance; }
静态内部类延迟加载的单列模式
/** * 静态内部类延迟加载的单列模式 * 外部类加载时,不会加载内部类,不会执行new InnerSingleton(); * 这就属于延迟加载,而且只有第一次调用getInstance方法时才会加载内部类 * 线程安全的 */ public class InnerSingleton { private InnerSingleton(){} private static class Inner{ private static InnerSingleton instance = new InnerSingleton(); } public static InnerSingleton getInstance(){ return Inner.instance; } }
-
枚举实现单列模式
/** * 枚举实现单列模式 */ public class EnumSingleton { private EnumSingleton(){} private static enum SingleEnum{ SINGLE; private EnumSingleton es = new EnumSingleton(); } public static EnumSingleton getInstance(){ return SingleEnum.SINGLE.es; } }