首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | java性能调优热点问题解答
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | MySQL调优之SQL语句:如何写出高性能SQL语句?
33 | MySQL调优之事务:高并发场景下的数据库事务调优
34 | MySQL调优之索引:索引的失效与优化
35 | 记一次线上SQL死锁事故:如何避免死锁?
36 | 什么时候需要分表分库?
37 | 电商系统表设计优化案例分析
38 | 数据库参数设置优化,失之毫厘差之千里
当前位置:
首页>>
技术小册>>
Java性能调优实战
小册名称:Java性能调优实战
### 27 | 单例模式:如何创建单一对象优化系统性能? 在软件开发中,特别是在Java等面向对象编程语言中,设计模式是解决问题的一种通用方案。单例模式(Singleton Pattern)作为设计模式中的一种,其核心思想是确保一个类仅有一个实例,并提供一个全局访问点来获取这个唯一实例。这种模式在多种场景下都非常有用,尤其是当对象的创建开销较大、资源有限或对象状态需要全局共享时。正确实现单例模式不仅能有效管理资源,还能显著提升系统性能,减少不必要的对象创建和销毁开销。 #### 一、单例模式的基本概念 单例模式的关键点在于保证类的全局唯一性和对其实例的受控访问。这意味着无论程序如何运行,该类在JVM中只会有一个实例存在,且这个实例的创建过程由程序严格控制。单例模式通过私有化构造函数、提供一个静态的私有变量来保存唯一实例,以及提供一个公共的静态方法来获取这个实例来实现。 #### 二、单例模式的实现方式 ##### 2.1 懒汉式(线程不安全) 懒汉式单例模式在第一次被请求时才会实例化对象,之后每次调用都会直接返回这个实例。但基本实现方式在多线程环境下是不安全的。 ```java public class SingletonLazyUnsafe { private static SingletonLazyUnsafe instance; private SingletonLazyUnsafe() {} public static SingletonLazyUnsafe getInstance() { if (instance == null) { instance = new SingletonLazyUnsafe(); } return instance; } } ``` **问题**:在多线程环境下,两个线程可能同时进入`if`语句块,导致创建多个实例。 ##### 2.2 懒汉式(线程安全) 为了解决懒汉式单例在多线程环境下的线程安全问题,可以通过加锁(如使用`synchronized`关键字)来实现。 ```java public class SingletonLazySafe { private static SingletonLazySafe instance; private SingletonLazySafe() {} public static synchronized SingletonLazySafe getInstance() { if (instance == null) { instance = new SingletonLazySafe(); } return instance; } } ``` **改进**:虽然解决了线程安全问题,但每次调用`getInstance()`方法时都需要进行线程锁定,影响性能。 ##### 2.3 双重检查锁定(Double-Checked Locking) 双重检查锁定模式既保证了线程安全,又减少了同步的开销。 ```java public class SingletonDoubleCheckedLocking { // 使用 volatile 关键字防止指令重排序 private static volatile SingletonDoubleCheckedLocking instance; private SingletonDoubleCheckedLocking() {} public static SingletonDoubleCheckedLocking getInstance() { if (instance == null) { synchronized (SingletonDoubleCheckedLocking.class) { if (instance == null) { instance = new SingletonDoubleCheckedLocking(); } } } return instance; } } ``` **注意**:必须使用`volatile`关键字来防止指令重排序导致的实例化问题。 ##### 2.4 静态内部类 静态内部类方式利用了类加载机制来保证实例的唯一性,并且实现了懒加载。 ```java public class SingletonStaticInnerClass { private SingletonStaticInnerClass() {} private static class SingletonHolder { private static final SingletonStaticInnerClass INSTANCE = new SingletonStaticInnerClass(); } public static final SingletonStaticInnerClass getInstance() { return SingletonHolder.INSTANCE; } } ``` **优点**:无需同步,线程安全,且实现了懒加载。 ##### 2.5 枚举方式 枚举方式是单例模式的最佳实现方式,它自动支持序列化机制,防止多次实例化,并且在多线程环境下也是安全的。 ```java public enum SingletonEnum { INSTANCE; public void someMethod() { // 方法实现 } } ``` **优点**:简洁,自动支持序列化机制,防止反序列化重新创建新的对象。 #### 三、单例模式在性能优化中的应用 单例模式通过确保类的唯一实例,减少了对象创建和销毁的开销,从而优化了系统性能。在以下场景中,单例模式尤其有用: 1. **数据库连接池**:数据库连接是昂贵的资源,通过单例模式管理连接池,可以减少连接的频繁建立和关闭,提高数据库访问效率。 2. **日志系统**:日志记录是系统中常见的功能,通过单例模式管理日志记录器,可以确保日志信息的全局统一处理,避免重复创建日志记录器实例。 3. **配置管理类**:应用程序中常有一些全局配置信息,如数据库配置、系统参数等,使用单例模式管理这些配置信息,可以方便地在整个应用中访问和修改这些配置。 4. **缓存系统**:缓存是提高系统性能的重要手段,通过单例模式管理缓存实例,可以避免缓存数据的重复加载和存储,提高缓存的利用率。 5. **线程池**:线程是系统中的重要资源,频繁地创建和销毁线程会带来较大的开销。使用单例模式管理线程池,可以复用线程资源,减少线程创建和销毁的开销。 #### 四、单例模式的注意事项 1. **延迟加载与饿汉式**:根据实际需求选择懒加载或饿汉式。如果实例的创建开销不大,且实例化时机可预测,可以使用饿汉式;否则,使用懒加载。 2. **序列化问题**:如果单例类实现了`Serializable`接口,在反序列化时可能会重新创建实例,破坏单例特性。使用枚举方式可以避免这个问题。 3. **线程安全问题**:在多线程环境下,必须确保单例实现是线程安全的。 4. **单例的扩展性**:在设计单例类时,应考虑未来可能的扩展需求,如是否需要支持多个实例等。 5. **代码可读性**:虽然单例模式实现方式多样,但应尽量选择简单、易理解且符合当前项目需求的实现方式。 #### 五、结论 单例模式是一种简单而强大的设计模式,通过确保类的全局唯一性和提供受控的访问方式,有效管理资源,提升系统性能。在Java开发中,合理选择单例模式的实现方式,并根据实际场景进行优化,对于提高系统性能和稳定性具有重要意义。无论是数据库连接池、日志系统、配置管理类还是缓存系统,单例模式都能发挥其独特的作用,助力开发者构建高效、稳定的系统。
上一篇:
25 | 内存持续上升,我该如何排查问题?
下一篇:
28 | 原型模式与享元模式:提升系统性能的利器
该分类下的相关小册推荐:
Java语言基础13-类的加载和反射
Java语言基础4-数组详解
Java语言基础10-Java中的集合
Java并发编程
Mybatis合辑3-Mybatis动态SQL
Java语言基础6-面向对象高级
SpringBoot零基础到实战
Java语言基础9-常用API和常见算法
Java语言基础2-运算符
Java语言基础1-基础知识
java源码学习笔记
Mybatis合辑2-Mybatis映射文件