单例模式(Singleton Pattern):确保一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。
一、饿汉单例
package com.miselehe.pattern.single; /** * <p>Title: HungerSingle</p> * <p>Description: 饿汉式单例模式 * 类加载时及初始化(线程安全) * 1. 构造方法私有 * 2. 静态成员变量实例化单例 * 3. 提供静态方法返回静态变量 * * * 有点:没有加任何的锁,执行效率比较高 * 用户体验比懒汉式更好 * * 缺点:不论使用不使用都占用内存 * </p> * @author 78250 * @date 2018年6月12日 - 下午5:48:26 */ public class HungerSingle { /** * 构造方法私有 */ private HungerSingle() { super(); // TODO Auto-generated constructor stub } /** * 静态成员变量实例化单例 */ private static final HungerSingle HUNGER_SINGLE = new HungerSingle(); /** * * <p>Title: getInstance</p> * <p>Description: 提供静态方法返回静态变量</p> * @author 78250 * @date 2018年6月12日 - 下午5:52:37 * @return */ public static HungerSingle getInstance() { return HUNGER_SINGLE; } }
二、懒汉单例
package com.miselehe.pattern.single; /** * <p>Title: LazySingle</p> * <p>Description: 懒汉式单例模式 * 第一次调用时,实例化单例(线程不安全) * 1. 构造方法私有 * 2. 静态成员变量引用单实例,但不初始化 * 3. 在第一次被调用时,根据是否被初始化实例化单实例 * </p> * @author 78250 * @date 2018年6月12日 - 下午6:07:45 */ public class LazySingle { /** * 构造方法私有 */ private LazySingle() { super(); // TODO Auto-generated constructor stub } /** * 静态成员变量 类加载时不实例化单例 */ private static LazySingle lazySingle = null; /** * * <p>Title: getInstance</p> * <p>Description: 静态方法获取单实例 * 此时根据静态变量实例化单例</p> * @author 78250 * @date 2018年6月12日 - 下午6:11:47 * @return */ public static LazySingle getInstance () { if (lazySingle == null) { lazySingle = new LazySingle(); } return lazySingle; } }
package com.miselehe.pattern.single; /** * <p>Title: SynchronizedLazySingle</p> * <p>Description: 懒汉模式增加线程安全</p> * @author 78250 * @date 2018年6月12日 - 下午6:48:55 */ public class SynchronizedLazySingle { /** * 静态成员变量引用,但不初始化 */ private static SynchronizedLazySingle single = null; /** * 构造方法私有 */ private SynchronizedLazySingle() { super(); // TODO Auto-generated constructor stub } /** * * <p>Title: getInstance</p> * <p>Description: 增加线程安全锁</p> * @author 78250 * @date 2018年6月12日 - 下午6:51:33 * @return */ public static synchronized SynchronizedLazySingle getInstance () { if (single == null) { single = new SynchronizedLazySingle(); } return single; } }
三、通过内部类初始化单例
package com.miselehe.pattern.single; /** * <p>Title: InnerClassLazySingle</p> * <p>Description: 通过内部类初始化单例 * 利用特性:内部类只有在外部类被调用的时候,才会被加载 * * 推荐:1. 避免了饿汉式单例内存一定开销 * 2. 也避免了synchronized的资源开销 * * </p> * @author 78250 * @date 2018年6月12日 - 下午6:55:00 */ public class InnerClassLazySingle { /** * 构造方法私有 * (如何防止反射入侵) */ private InnerClassLazySingle() { // TODO Auto-generated constructor stub } /** * * <p>Title: getInstance</p> * <p>Description: 提供静态方法返回内部类属性</p> * @author 78250 * @date 2018年6月12日 - 下午7:03:20 * @return */ public static final InnerClassLazySingle getInstance () { return LazyHolder.single; } /** * * <p>Title: LazyHolder</p> * <p>Description: 内部类, 静态成员变量初始化外部类(单例类) * 虽然此为静态变量,但是此内部类的加载是在外部类调用时进行的 * </p> * @author 78250 * @date 2018年6月12日 - 下午7:03:52 */ private static class LazyHolder { private static final InnerClassLazySingle single = new InnerClassLazySingle(); } }