设计模式系列—单例设计模式( 二 )
这种单例模式可用 , 但是如果不用 , 可能会造成内存的浪费 。
懒汉式(线程不安全)代码示例package com.niuh.designpattern.singleton.v3;/** * * 懒汉式(线程不安全) */public class Singleton {private static Singleton instance;// 构造函数私有化private Singleton() {}// 提供一个静态的公共方法 , 当使用到该方法时 , 才创建 instance , 即懒汉式public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}class SingletonTest02 {public static void main(String[] args) {// 测试for (int i = 0; i< 100; i++) {new Thread(() ->System.out.println(Singleton.getInstance().hashCode())).start();}}}
优缺点
- 起到了 懒加载 的效果 , 但是只能在 单线程下使用;
- 如果在多线程下 , 一个线程进入了 if(instance == null) 判断语句块 , 可能另外一个线程也通过了这个语句判断 , 这是会产生多个实例 , 所以在多线程环境下不可使用这种方式 。
懒汉式(线程安全 , 同步方法)代码示例
/** * 懒汉式(线程安全 , 同步方法) */public class Singleton {private static Singleton instance;// 构造函数私有化private Singleton() {}// 提供一个静态的公有方法 , 加入同步处理的代码 , 解决线程安全问题public static synchronizedSingleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}
注:加入关键字保证线程安全问题 synchronized优缺点
- 虽然加入保证线程安全的关键字 , 解决线程安全问题(其实实际上并不一定线程安全:编译器(JIT),CPU 有可能对指令进行重排序)
- 效率低下 , 每个线程在想获得实例的时候 , 执行 getInstance 方法都要进行同步 。 方法的同步效率太低 。
懒汉式(线程安全 , 同步代码块)代码示例
/** * 懒汉式(线程安全 , 同步代码块) */public class Singleton {private static Singleton instance;// 构造函数私有化private Singleton() {}// 提供一个静态的公有方法 , 加入同步处理的代码 , 解决线程安全问题public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {instance = new Singleton();}}return instance;}}
优缺点虽然对加锁处做了一定优化 , 总体优缺点同上面一致 。双重检查(DCL)代码示例
/** * 双重检查 DCL */public class Singleton {// 添加 volatile 关键字 , 防止指令重排private static volatile Singleton instance;// 构造函数私有化private Singleton() {}// 提供对外引用的静态方法 , 使用双重检查机制 double checkpublic static Singleton getInstance() {if (instance == null) { // Double Check Lock// 双重检查synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}}
编译器(JIT),CPU 有可能对指令进行重排序 , 导致使用到尚未初始化的实例 , 可以通过添加volatile 关键字进行修饰优缺点
- Double-Check 概念是多线程开发中常使用到的 , 如代码中所示 , 我们进行了两次 if(singleton== null) 检查 , 这样就可以保证线程安全了
- 实例化代码只用执行一次 , 后面在进行访问的时候 , 判断 if(singleton== null) , 直接 return 实例化对象 , 也避免了反复进行方法同步 。
- SpringBoot2.x入门到项目实战课程系列(第二章)
- 设计模式6之代理模式
- 三星Note10系列One UI Beta版计划正式推送
- LetsGoDigital分享三星Galaxy S21系列全家桶渲染图
- AMD锐龙5000系列处理器曝光 Zen3架构加持性能提升
- 不愧为华为的“狼崽”,刚撇清关系没多久,一系列的动作随之而来
- 三星Galaxy S20系列壁纸,拥有不错的质感
- 华为mate40系列外观确定,两个版本两种设计
- RX 6950?AMD还有顶级大招?
- 一条搞定所有接口,倍思闪速系列二拖三PD快充线评测