Java一分钟之-设计模式:单例模式的实现

本文涉及的产品
应用实时监控服务-用户体验监控,每月100OCU免费额度
应用实时监控服务-应用监控,每月50GB免费额度
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 【5月更文挑战第16天】本文介绍了单例模式的四种实现方式:饿汉式(静态初始化)、懒汉式(双检锁)、静态内部类和枚举单例,以及相关问题和解决方法。关注线程安全、反射攻击、序列化、生命周期和测试性,选择合适的实现方式以确保代码质量。了解单例模式的优缺点,谨慎使用,提升设计效率。

单例模式是一种常见的设计模式,用于确保一个类只有一个实例,并提供全局访问点。本文将介绍单例模式的几种实现方式,以及相关的常见问题、易错点和如何避免它们。
image.png

1. 饿汉式(Static Singleton)

在类加载时就创建实例,线程安全,但可能导致不必要的资源浪费。

public class Singleton {
   
   
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {
   
   }

    public static Singleton getInstance() {
   
   
        return INSTANCE;
    }
}

2. 懒汉式(DCL,Double-Checked Locking)

延迟初始化,只有在首次使用时才创建实例。使用volatile关键字保证可见性和有序性。

public class Singleton {
   
   
    private volatile static Singleton INSTANCE;

    private Singleton() {
   
   }

    public static Singleton getInstance() {
   
   
        if (INSTANCE == null) {
   
   
            synchronized (Singleton.class) {
   
   
                if (INSTANCE == null) {
   
   
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}

3. 静态内部类(Thread-safe Lazy Initialization)

利用类加载机制保证线程安全,延迟初始化。

public class Singleton {
   
   
    private Singleton() {
   
   }

    private static class SingletonHolder {
   
   
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
   
   
        return SingletonHolder.INSTANCE;
    }
}

4. 枚举单例

最简洁、安全的实现方式,天然线程安全,防止反射攻击。

public enum Singleton {
   
   
    INSTANCE;
}

5. 常见问题与解决

5.1 反射攻击

通过反射创建新的实例,绕过单例约束。枚举单例可以防止这种情况。

Singleton singleton = Singleton.class.getDeclaredConstructor().newInstance();

5.2 序列化与反序列化

单例对象被序列化和反序列化时,可能会创建多个实例。在单例类上实现readResolve()方法来返回已存在的实例。

private Object readResolve() {
   
   
    return INSTANCE;
}

5.3 单例的生命周期

单例的生命周期与应用相同,如果需要在特定条件下销毁,需要额外处理。

6. 易错点与避免方法

6.1 避免在静态初始化器中创建实例

静态初始化器在类加载时执行,可能导致不必要的实例化。

6.2 注意线程安全

在多线程环境中,确保单例的创建是线程安全的。

6.3 考虑可测试性

设计单例时,考虑测试需求,如提供构造函数的友元访问。

7. 结语

单例模式在许多场景下都非常有用,但使用时需谨慎,避免滥用。理解各种实现方式及其优缺点,根据项目需求选择合适的方法。同时,注意单例的生命周期、线程安全和测试性,以确保代码的质量和可维护性。


掌握单例模式的实现方式,有助于你在实际项目中更好地组织代码和管理资源。不断学习和实践,将使你的设计更加优雅和高效。

目录
相关文章
|
3月前
|
设计模式 安全 Java
Java编程中的单例模式深入剖析
【10月更文挑战第21天】在Java的世界里,单例模式是设计模式中一个常见而又强大的存在。它确保了一个类只有一个实例,并提供一个全局访问点。本文将深入探讨如何正确实现单例模式,包括常见的实现方式、优缺点分析以及最佳实践,同时也会通过实际代码示例来加深理解。无论你是Java新手还是资深开发者,这篇文章都将为你提供宝贵的见解和技巧。
107 65
|
24天前
|
设计模式 存储 前端开发
前端必须掌握的设计模式——单例模式
单例模式是一种简单的创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。适用于窗口对象、登录弹窗等场景,优点包括易于维护、访问和低消耗,但也有安全隐患、可能形成巨石对象及扩展性差等缺点。文中展示了JavaScript和TypeScript的实现方法。
|
29天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
25 2
|
2月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
2月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
40 4
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
2月前
|
设计模式 安全 Java
Java编程中的单例模式:理解与实践
【10月更文挑战第31天】在Java的世界里,单例模式是一种优雅的解决方案,它确保一个类只有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的实现方式、使用场景及其优缺点,同时提供代码示例以加深理解。无论你是Java新手还是有经验的开发者,掌握单例模式都将是你技能库中的宝贵财富。
57 2
|
2月前
|
设计模式 安全 Java
Java编程中的单例模式深入解析
【10月更文挑战第31天】在编程世界中,设计模式就像是建筑中的蓝图,它们定义了解决常见问题的最佳实践。本文将通过浅显易懂的语言带你深入了解Java中广泛应用的单例模式,并展示如何实现它。
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
2月前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
24 1