设计模式之单例模式用法详解
发布日期:2021-10-09 15:35:05 浏览次数:1 分类:技术文章

本文共 3210 字,大约阅读时间需要 10 分钟。

定义

单例模式是指在一个应用(JVM)中,对于某个类的实例只能有一个,所有对于某个类实例的访问都是对于同一个对象的访问

优点:在内存中只有一个实例,减少了内存开销。可以避免对资源的多重占用,设置全局访问点,严格控制访问。
缺点:没有接口,扩展困难。如果需要扩展单例对象,只能修改代码,没有其它途径。

框架实例

ServletContext, ServletConfig, ApplicationContext, DBPool

常见实现方式

实现方式 描述
饿汉式单例 单例类首次加载的时候就会创建实例,会存在反序列化和反射注入破坏单例问题
懒汉式单例 在单例类的实例被使用的时候才创建实例对象,会存在序列化和反射注入破坏单例问题
注册式单例 分为枚举式单例(JDK层面枚举不支持被反射注入和序列化问题)和容器式单例,能解决序列化和反射注入破环单例

代码实现

  1. 饿汉式单例模式
package com.architecture.pattern.singleton;/** * @Auth yangyongp * @Create 2020/7/3 22:58 */public class HungrySingletonDemo {  private static final HungrySingletonDemo instance;  static {    instance = new HungrySingletonDemo();  }  private HungrySingletonDemo(){  }  public static HungrySingletonDemo getInstance(){    return instance;  }}
package com.architecture.pattern.singleton;/** * @Auth yangyongp * @Create 2020/7/3 23:01 */public class HungrySingletonDemo2 {  private static final HungrySingletonDemo2 instance = new HungrySingletonDemo2();  private HungrySingletonDemo2(){  }    public static HungrySingletonDemo2 getInstance(){    return instance;  }}

2.懒汉式单例模式

package com.architecture.pattern.singleton;/** * @Auth yangyongp * @Create 2020/7/3 23:06 */public class LazySingletonDemo {  private static LazySingletonDemo instance = null;  private LazySingletonDemo(){  }  public static LazySingletonDemo getInstance(){    if(instance == null){      synchronized (LazySingletonDemo.class){        if(instance == null){          instance = new LazySingletonDemo();        }      }    }    return instance;  }}
package com.architecture.pattern.singleton;/** * @Auth yangyongp * @Create 2020/7/14 21:42 */public class LazyInnerClasssSingletonDemo {  private LazyInnerClasssSingletonDemo(){  }  /**   * 懒汉式单例   * LazyHolder里面的逻辑需要等到外部方法调用时才执行   * 巧妙利用了内部的特性   * JVM底层执行逻辑,避免了线程安全问题   * @return   */  public static LazyInnerClasssSingletonDemo getInstance(){    return LazyHolder.LAZY;  }  private static class LazyHolder{    private static final LazyInnerClasssSingletonDemo LAZY = new LazyInnerClasssSingletonDemo();  }}
  1. 注册式单例
    a.枚举式单例
    从JDK层面就为枚举不被序列化和反射破坏来保驾护航
package com.architecture.pattern.singleton;/** * @Auth yangyongp * @Create 2020/7/3 23:10 */public enum EnumSingletonDemo {  INSTANCE;  private Object data;  public Object getData() {    return data;  }  public void setData(Object data) {    this.data = data;  }  public static EnumSingletonDemo getInstance(){    return INSTANCE;  }}

b.容器式

package com.architecture.pattern.singleton;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/** * @Auth yangyongp * 对象方便管理,其实也是属于懒加载 * @Create 2020/7/14 22:25 */public class ContainerSingletonDemo {  private ContainerSingletonDemo(){  }  private static Map
ioc = new ConcurrentHashMap<>(); public static Object getBean(String className){ if(!ioc.containsKey(className)){ synchronized (ioc){ if(!ioc.containsKey(className)){ Object obj = null; try{ obj = Class.forName(className).newInstance(); ioc.put(className, obj); }catch (Exception ex){ ex.printStackTrace(); } return obj; } } } return ioc.get(className); }}

相关知识点

1.私有构造方法

2.保证线程安全
3.延迟加载
4.防止序列化和反序列化破坏单例
5.防止反射攻击

转载地址:https://blog.csdn.net/qinwuxian19891211/article/details/107116990 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:springboot Json序列化时如何忽略部分字段
下一篇:maven如何快速查找某个包哪里引入的

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月04日 13时51分55秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章