当前位置: 首页 > news >正文

JAVA设计模式之【单例模式】

单例模式.png

1 类图

2 饿汉式单例

例如:静态块、静态成员

2.1 概念

类加载的时候就立即初始化,并且创建单例对象

2.2 优点

没有加任何的锁、执行效率比较高

2.3 缺点

类加载的时候就初始化,不管用与不用都占着空间,浪费了内存。

3 懒汉式单例

3.1 直接:线程不安全

public class LazySimpleSingleton {private LazySimpleSingleton(){}//静态块,公共内存区域private static LazySimpleSingleton lazy = null;public  static LazySimpleSingleton getInstance(){if(lazy == null){lazy = new LazySimpleSingleton();}return lazy;}
}

3.2 同步方法

public class LazySimpleSingleton {private LazySimpleSingleton(){}//静态块,公共内存区域private static LazySimpleSingleton lazy = null;public synchronized static LazySimpleSingleton getInstance(){if(lazy == null){lazy = new LazySimpleSingleton();}return lazy;}
}

3.2.1 优化CPU:双重检查锁

public class LazyDoubleCheckSingleton {private volatile static LazyDoubleCheckSingleton lazy = null;private LazyDoubleCheckSingleton(){}public static LazyDoubleCheckSingleton getInstance(){if(lazy == null){synchronized (LazyDoubleCheckSingleton.class){if(lazy == null){lazy = new LazyDoubleCheckSingleton();//1.分配内存给这个对象//2.初始化对象//3.设置lazy指向刚分配的内存地址//4.初次访问对象}}}return lazy;}
}

3.2.2 IDEA 环境下的多线程调试

3.3 静态内部类

这种形式兼顾饿汉式的内存浪费,也兼顾synchronized性能问题,完美地屏蔽了这两个缺点

//史上最牛B的单例模式的实现方式
public class LazyInnerClassSingleton {//默认使用LazyInnerClassGeneral的时候,会先初始化内部类//如果没使用的话,内部类是不加载的private LazyInnerClassSingleton(){if(LazyHolder.LAZY != null){throw new RuntimeException("不允许创建多个实例");}}//每一个关键字都不是多余的//static 是为了使单例的空间共享//保证这个方法不会被重写,重载public static final LazyInnerClassSingleton getInstance(){//在返回结果以前,一定会先加载内部类return LazyHolder.LAZY;}//默认不加载private static class LazyHolder{private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();}
}

3.3.1 反射破坏单例

在构造函数上抛出异常

    private LazyInnerClassSingleton(){if(LazyHolder.LAZY != null){throw new RuntimeException("不允许创建多个实例");}}

3.3.2 序列化破坏单例

增加 readResolve()方法

public class SeriableSingleton implements Serializable {public  final static SeriableSingleton INSTANCE = new SeriableSingleton();private SeriableSingleton(){}public static SeriableSingleton getInstance(){return INSTANCE;}private  Object readResolve(){return  INSTANCE;}
}

4 注册式单例

4.1 枚举式单例

利用jdk特性。具有线程安全、实例唯一(杜绝反序列化破坏单例)的特点。
public enum EnumSingleton {INSTANCE;private Object data;public Object getData() {return data;}public void setData(Object data) {this.data = data;}public static EnumSingleton getInstance(){return INSTANCE;}
}

4.1.1 优点

线程安全、实例唯一

4.2 容器缓存写法

public class ContainerSingleton {private ContainerSingleton(){}private static Map<String,Object> ioc = new ConcurrentHashMap<String,Object>();public static Object getInstance(String className){synchronized (ioc) {if (!ioc.containsKey(className)) {Object obj = null;try {obj = Class.forName(className).newInstance();ioc.put(className, obj);} catch (Exception e) {e.printStackTrace();}return obj;} else {return ioc.get(className);}}}
}

4.2.1 优点

对象方便管理、懒加载

4.2.2 缺点

不加上synchronized存在线程安全问题

5 ThreadLocal-线程单例

5.1 写法

public class ThreadLocalSingleton {private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance =new ThreadLocal<ThreadLocalSingleton>(){@Overrideprotected ThreadLocalSingleton initialValue() {return new ThreadLocalSingleton();}};private ThreadLocalSingleton(){}public static ThreadLocalSingleton getInstance(){return threadLocalInstance.get();}
}

5.2 优点

保证在单个线程中是唯一


http://www.mrgr.cn/news/5908.html

相关文章:

  • 一文掌握 Web 测试:功能、界面、兼容与安全的综合测试指南!
  • 【数据分析】数据的离中趋势之一 - 极差、分位距、平均差
  • Jenkins配置SSH凭据
  • CSS的:required和:optional伪类:增强表单字段的视觉识别
  • 【设计模式】建造者模式和单例模式
  • Redis笔记-分布式存储方案中哨兵模式配置
  • oracle数据库缓存区高速缓存区
  • Java导出分类到Excel
  • 从HTTP到HTTPS:SSL加密如何重塑互联网安全格局
  • 机器学习:决策树回归树实现
  • 开发一个免费的图表网站 Free Charts
  • 数据结构-单调栈
  • 视频美颜SDK与直播美颜工具的开发详解与技术优化
  • Llama 3.1 70B与Mistral Large 2 128B深度对比
  • MATLAB CSF布料模拟滤波分类地面点和地物点(71)
  • Tauri简介
  • Docker离线安装
  • Swift 6.0 如何更优雅的抛出和处理特定类型的错误
  • Android 14适配
  • C# 使用M2Mqtt库开发MQTT通信协议