单例模式

单例模式
  • 应用场景:
    • 有些对象只需要一个配置文件、工具类、线程池、缓存、日志对象等。
    • 如果创造多个实例就会导致许多问题,比如占用过多的资源、不一致的结果等。
  • 作用:保证整个应用程序中某个实例有且仅有一个。
  • 两种类型: 饿汉模式和懒汉模式。
  • 代码示例
/**
  *饿汉模式
  */
  public class HungrySingleton {
		 // 1. 构造器私有化--不允许外部直接创建对象
		 private HungrySingleton() {
		 }

		 // 2. 创建类的唯一实例
		 private static HungrySingleton hungrySingleton = new HungrySingleton();

		 // 3. 提供对外获取实例的接口
		 public static HungrySingleton getInstance() {
		 	return hungrySingleton;
		 }
}

/**
  *饿汉模式 
  *提高效率-->巧妙利用类在使用时加载的特点,避免在该类调用其他方法时再次始化hungrySingleton,
  *除非调用初始化方法。初始化过一次就不用再初始化,提高效率
  */
  public class HungrySingleton {
		 // 1. 构造器私有化--不允许外部直接创建对象
		 private HungrySingleton() {
		 }

		 // 2. 在嵌套类中创建类的唯一实例
		 private static class Holder{
			 private static HungrySingleton hungrySingleton = new HungrySingleton();
		 }

		 // 3. 提供对外获取实例的接口
		 public static HungrySingleton getInstance() {
		 	return Holder.hungrySingleton;
		 }
		 
		 // 4. 存在的其他方法
		 // ...
}

/**
 *懒汉模式(线程不安全)
 */
 public class LazySingleton {
		// 1. 构造器私有化--不允许外部直接创建对象
		private LazySingleton() {
		}

		// 2. 声明类的唯一实例
		private static LazySingleton lazySingleton;

		// 3. 提供对外获取实例的接口
		public static LazySingleton getInstance() {
			if (null == lazySingleton) {
				lazySingleton = new LazySingleton();
			}
			return lazySingleton;
		}
}

/**
 *懒汉模式(线程安全的方式 -- synchronized关键字方式1 效率不高)
 */
 public class LazySingleton {
		// 1. 构造器私有化--不允许外部直接创建对象
		private LazySingleton() {
		}

		// 2. 声明类的唯一实例
		private static LazySingleton lazySingleton;

		// 3. 提供对外获取实例的接口
		public synchronized static LazySingleton getInstance() {
			if (null == lazySingleton) {
				lazySingleton = new LazySingleton();
			}
			return lazySingleton;
		}
}

/**
 *懒汉模式(线程安全的方式 -- synchronized关键字方式2 效率不高)
 */
 public class LazySingleton {
		// 1. 构造器私有化--不允许外部直接创建对象
		private LazySingleton() {
		}

		// 2. 声明类的唯一实例
		private static LazySingleton lazySingleton;

		// 3. 提供对外获取实例的接口
		public static LazySingleton getInstance() {
			synchronized(LazySingleton.class){
				if (null == lazySingleton) {
					lazySingleton = new LazySingleton();
				}
			}
			return lazySingleton;
		}
}

/**
 *懒汉模式(线程安全的方式 -- synchronized关键字方式3 效率提高)
 *提高效率-->Double checking
 */
 public class LazySingleton {
		// 1. 构造器私有化--不允许外部直接创建对象
		private LazySingleton() {
		}

		// 2. 声明类的唯一实例
		private static LazySingleton lazySingleton;

		// 3. 提供对外获取实例的接口
		public static LazySingleton getInstance() {
			if(null == lazySingleton) // 提高效率
				synchronized(LazySingleton.class){
					if (null == lazySingleton) { // 确保唯一
						lazySingleton = new LazySingleton();
					}
					return lazySingleton;
				}
			return lazySingleton;
		 }
}

/**
 *懒汉模式(线程安全的方式 --  -- synchronized关键字方式4)
 *以上三种synchronized关键字的使用方式在一般情况下不会出现问题
 *但是在并发量特别大的情况下,线程依然不是安全的,这个时候就需要volatile关键字了
 *原因:lazySingleton = new LazySingleton();不是原子操作
 *lazySingleton = new LazySingleton();大致做了3件事情:
 *第一步:分配内存。
 *第二步:调用构造方法初始化。
 *第三步:将lazySingleton对象指向分配空间。
 *由于Java处理器存在指令重排序的情况,所以这三步的执行顺序不定,如果执行完第一步和第三步后,其他的线程使用lazySingleton就会报错未实例化。
 */
 public class LazySingleton {
		// 1. 构造器私有化--不允许外部直接创建对象
		private LazySingleton() {
		}

		// 2. 声明类的唯一实例
		private volatile static LazySingleton lazySingleton;

		// 3. 提供对外获取实例的接口
		public static LazySingleton getInstance() {
			if(null == lazySingleton) // 提高效率
				synchronized(LazySingleton.class){
					if (null == lazySingleton) { // 确保唯一
						lazySingleton = new LazySingleton();
					}
					return lazySingleton;
				}
			return lazySingleton;
		 }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值