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

建设厅投诉网站/百度经验官网

建设厅投诉网站,百度经验官网,独立商城系统网站建设等服务器,企业建网站的步骤一、单例模式的定义 (Singleton Pattern Definition) 单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例。 核心思想: 限制实例化: 防止外部通过 new 关键字创建类的多个实例。…

一、单例模式的定义 (Singleton Pattern Definition)

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例。

核心思想:

  • 限制实例化: 防止外部通过 new 关键字创建类的多个实例。
  • 自我创建: 类自身负责创建自己的唯一实例。
  • 全局访问: 提供一个静态方法或静态变量,允许全局访问这个唯一实例。

二、单例模式的目的 (Purpose of Singleton Pattern)

单例模式的主要目的是:

  1. 控制实例数量: 确保一个类在任何情况下都只有一个实例存在。
  2. 节省资源: 避免创建多个相同的对象,节省内存空间和系统资源(例如,创建对象是一个耗时的操作)。
  3. 全局访问: 提供一个全局访问点,方便其他对象访问这个唯一实例,无需传递对象引用。
  4. 数据共享: 在多个模块或组件之间共享数据或状态。
  5. 协调行为: 协调系统中的不同部分的行为,例如,确保只有一个线程池、一个缓存管理器、一个配置对象等。

三、单例模式的实现方式 (Singleton Pattern Implementations)

单例模式有多种实现方式,每种方式都有其优缺点。 以下是常见的几种实现方式:

  1. 饿汉式 (Eager Initialization):

    • 原理: 在类加载时就立即创建单例实例。

    • 优点:

      • 简单,易于实现。
      • 线程安全(由 JVM 保证)。
      • 获取实例的速度快(无需延迟加载)。
    • 缺点:

      • 无论是否使用该实例,都会在类加载时创建,可能造成资源浪费(如果实例的创建比较耗时,或者实例很大)。
      • 无法实现延迟加载。
    • 代码示例:

      public class EagerSingleton {// 私有静态成员变量,在类加载时就创建实例private static final EagerSingleton instance = new EagerSingleton();// 私有构造方法,防止外部创建实例private EagerSingleton() {}// 公共静态方法,提供全局访问点public static EagerSingleton getInstance() {return instance;}
      }
      
  2. 懒汉式 (Lazy Initialization) - 线程不安全:

    • 原理: 延迟加载,只有在第一次使用时才创建单例实例。

    • 优点:

      • 避免了不必要的实例创建,节省资源。
      • 实现了延迟加载。
    • 缺点:

      • 线程不安全:在多线程环境下,可能会创建多个实例。
    • 代码示例:

      public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}// 线程不安全public static LazySingleton getInstance() {if (instance == null) { // 如果实例不存在,则创建instance = new LazySingleton();}return instance;}
      }
      
  3. 懒汉式 (Lazy Initialization) - 线程安全 (synchronized):

    • 原理:getInstance() 方法上加 synchronized 关键字,保证线程安全。

    • 优点:

      • 线程安全。
      • 实现了延迟加载。
    • 缺点:

      • 性能较低:每次调用 getInstance() 方法都需要进行同步,即使实例已经创建了。
    • 代码示例:

      public class LazySingletonSynchronized {private static LazySingletonSynchronized instance;private LazySingletonSynchronized() {}// 使用 synchronized 关键字保证线程安全public static synchronized LazySingletonSynchronized getInstance() {if (instance == null) {instance = new LazySingletonSynchronized();}return instance;}
      }
      
  4. 双重检查锁定 (Double-Checked Locking) - 线程安全 (需要 volatile):

    • 原理:getInstance() 方法中,先检查实例是否已经创建,如果未创建,再进行同步和创建。

    • 优点:

      • 线程安全。
      • 实现了延迟加载。
      • 性能较好(相比于直接在 getInstance() 方法上加 synchronized)。
    • 缺点:

      • 代码稍微复杂一些。
      • 需要使用 volatile 关键字来禁止指令重排序(JDK 1.5 之后)。
    • 代码示例:

      public class DoubleCheckedLockingSingleton {// 使用 volatile 关键字禁止指令重排序private volatile static DoubleCheckedLockingSingleton instance;private DoubleCheckedLockingSingleton() {}public static DoubleCheckedLockingSingleton getInstance() {if (instance == null) { // 第一次检查synchronized (DoubleCheckedLockingSingleton.class) { // 加锁if (instance == null) { // 第二次检查instance = new DoubleCheckedLockingSingleton();}}}return instance;}
      }
      
    • 为什么要使用 volatile 关键字?
      * instance = new DoubleCheckedLockingSingleton(); 这行代码不是原子操作,它实际上包含了三个步骤:
      1. 分配内存空间。
      2. 初始化对象。
      3. 将 instance 指向分配的内存空间。

      • 如果没有 volatile 关键字,可能会发生指令重排序,导致线程 A 在对象初始化完成之前就将 instance 指向了分配的内存空间,此时线程 B 访问 instance,会发现 instance 不为 null,但实际上对象还没有初始化完成,导致错误。
      • volatile 关键字可以禁止指令重排序,保证这三个步骤的顺序性。
  5. 静态内部类 (Static Inner Class) - 线程安全 (推荐)

    • 原理: 利用 Java 类加载机制来实现延迟加载和线程安全。 静态内部类只有在被使用时才会被加载。

    • 优点:

      • 线程安全(由 JVM 保证)。
      • 实现了延迟加载。
      • 代码简洁。
      • 性能较好。
    • 推荐: 这是实现单例模式的一种推荐方式。

    • 代码示例:

      public class StaticInnerClassSingleton {private StaticInnerClassSingleton() {}// 静态内部类private static class SingletonHolder {private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();}public static StaticInnerClassSingleton getInstance() {return SingletonHolder.INSTANCE; // 访问静态内部类的静态成员变量}
      }
      
  6. 枚举 (Enum) - 线程安全 (最佳实践)

    • 原理: Java 枚举类型本身就是单例的,JVM 保证枚举实例的唯一性。

    • 优点:

      • 线程安全(由 JVM 保证)。
      • 代码简洁。
      • 防止反射攻击和序列化破坏单例。
      • 最佳实践。
    • 推荐: 《Effective Java》作者 Josh Bloch 推荐使用枚举来实现单例模式。

    • 代码示例:

      public enum EnumSingleton {INSTANCE; // 唯一的枚举实例// 可以添加其他方法和属性public void doSomething() {System.out.println("EnumSingleton is doing something...");}
      }// 使用
      EnumSingleton.INSTANCE.doSomething();
      

四、单例模式的优缺点

  • 优点:

    • 控制实例数量,节省资源。
    • 提供全局访问点,方便使用。
    • 可以实现延迟加载 (懒汉式)。
    • 可以避免多线程并发访问同一个资源造成的冲突。
  • 缺点:

    • 违反单一职责原则: 单例类既负责创建和管理自身实例,又负责业务逻辑,职责不够单一。
    • 扩展困难: 如果需要创建多个实例,或者需要对单例类进行扩展,会比较困难。
    • 隐藏依赖关系: 单例模式的全局访问点可能会隐藏类之间的依赖关系,使代码难以理解和测试。
    • 可能导致内存泄漏: 如果单例对象持有对外部资源的引用,并且这些资源没有被及时释放,可能会导致内存泄漏。
    • 在分布式系统中难以实现真正的单例: 在分布式环境中,每个 JVM 都会创建一个单例实例,除非使用分布式锁或其他机制来保证全局唯一性。

五、单例模式的应用场景

  1. 需要频繁创建和销毁的对象: 如果对象的创建和销毁开销较大,可以使用单例模式来避免频繁创建和销毁对象,例如:

    • 线程池 (ThreadPoolExecutor): 管理线程资源,避免频繁创建和销毁线程。
    • 缓存 (Cache): 缓存数据,避免频繁从数据库或其他地方加载数据。
    • 数据库连接池 (Connection Pool): 管理数据库连接,避免频繁创建和关闭连接。
    • 配置加载类: 加载和管理配置信息
  2. 需要全局唯一或共享的对象:

    • 配置对象 (Configuration Object): 应用程序的配置信息通常只需要一个实例。
    • 日志记录器 (Logger): 应用程序的日志记录器通常只需要一个实例。
    • 计数器 (Counter): 全局唯一的计数器。
    • ID 生成器 (ID Generator): 全局唯一的 ID 生成器。
    • 应用程序上下文 (Application Context): 例如 Spring 中的 ApplicationContext
    • ServletContext: 在 Java Web 应用中,每个 Web 应用只有一个 ServletContext 对象。
    • Windows 系统的任务管理器,回收站 等。
  3. 控制资源访问:

    • 打印机 (Printer): 确保同一时间只有一个任务可以访问打印机。
    • 文件系统 (File System): 确保对同一个文件的访问是互斥的。
    • 硬件设备: 例如串口、显卡等,通常需要单例模式来控制访问。
  4. Spring Bean的默认作用域:

    • Spring Bean 的默认作用域就是 singleton

六、单例模式与其他设计模式的关系

  • 工厂模式 (Factory Pattern): 工厂模式可以用来创建单例对象。
  • 抽象工厂模式 (Abstract Factory Pattern): 抽象工厂模式也可以用来创建单例对象。
  • 建造者模式 (Builder Pattern): 可以用来构建复杂对象的单例。
  • 原型模式 (Prototype Pattern): 原型模式与单例模式冲突,原型模式要求每次都返回一个新对象。
  • 外观模式 (Facade Pattern): 外观类通常被设计为单例。

七、最佳实践和注意事项

  1. 选择合适的实现方式: 根据你的需求和场景选择最合适的单例模式实现方式。 推荐使用枚举静态内部类方式。
  2. 线程安全: 确保你的单例模式实现是线程安全的。
  3. 延迟加载: 如果单例对象的创建比较耗时,或者不一定会被使用,可以考虑使用延迟加载。
  4. 防止反射攻击: 可以通过在私有构造方法中进行判断,防止通过反射创建多个实例。
 private Singleton() {if (instance != null) {throw new IllegalStateException("Already instantiated");}}
  1. 防止序列化破坏单例: 如果单例类实现了 Serializable 接口,需要重写 readResolve() 方法,返回单例实例,防止反序列化创建多个实例。
      // readResolve to prevent another instance of Singleton
    private Object readResolve() {return instance; // 返回已存在的单例实例
    }
    
  2. 谨慎使用单例模式: 不要滥用单例模式。 单例模式会增加代码的耦合度,降低可测试性。 只有在确实需要全局唯一实例时才使用单例模式。
  3. 考虑依赖注入: 在 Spring 等框架中,可以使用依赖注入来管理单例对象,而不是自己实现单例模式。
  4. 分布式环境: 在分布式环境中,需要考虑如何实现全局唯一的单例,可以使用分布式锁、分布式配置中心等技术。
  5. 测试: 对单例类进行单元测试,确保其功能正确,并且只有一个实例被创建。

总结

单例模式是一种常用的设计模式,它可以确保一个类只有一个实例,并提供全局访问点。 单例模式有多种实现方式,每种方式都有其优缺点。 在使用单例模式时,需要考虑线程安全、延迟加载、反射攻击、序列化、以及分布式环境等问题。

http://www.whsansanxincailiao.cn/news/31960578.html

相关文章:

  • 网站建设排版规定/营销是做什么
  • 基于企业网站的网络营销方法/连接友谊
  • 网站建设与维护教案/销售网站怎么做
  • 壮族自治区桂林疫情情况 最新消息/seo快速优化排名
  • 怎么做推广和宣传企业做网站/seo怎么优化效果更好
  • 网站开发+语音/百度seo怎么把关键词优化上去
  • 亚马逊网站建设进度计划/营销网站搭建
  • 使用wordpress在ec2上建网站/网络营销和网站推广的区别
  • 建设厅投诉网站首页/app广告投放价格表
  • 广告网站布局/百度搜索引擎推广收费标准
  • 苏州网站建设机构/河北百度seo关键词排名
  • 深圳网络营销渠道/资源网站优化排名优化
  • 深圳设计馆/seo技术学院
  • 做旅游网站选什么空间/seo顾问赚钱吗
  • 微信网站开发企业/免费自助建站模板
  • 长沙专业网站制作设计/百度官方网站网址是多少
  • 电子商城市场/优化落实疫情防控新十条
  • 日照 网站建设/深度优化
  • 哪些网站做科技专题/企业软文营销
  • 吴川网站开发公司/抖音seo排名
  • 网站反链如何做/网站开发语言
  • 邯郸网站优化建设/企业营销网站
  • 虚拟主机做网站/爱站长工具
  • 一般做网站宽高多少/百度号码认证平台官网
  • 对单位网站的要求/百度后台登陆入口
  • 有什么网站可以做投票功能/网站的友情链接是什么意思
  • 湖南做电商网站需要什么条件/易观数据
  • 做网站组织结构框架例子/西地那非片吃了能延时多久
  • 如何让别人浏览我做的网站/seo数据
  • 有什么可以做兼职的网站/河南企业站seo