单例应该是一个入门的设计模式了。
先来复习一下Java原生的语法创建一个对象的语法:
// 创建一个 Book 对象
Obj obj = new Obj();
在 Java 中,使用 new Obj()
创建对象是常见的做法,但在某些特定场景下,单例设计模式(Singleton Pattern)是一个更好的选择。单例设计模式保证一个类只有一个实例,并提供全局访问点。让我们探讨一下为什么有时需要单例设计模式,以及它的适用场景。
单例设计模式的需求场景
-
资源共享:
- 场景: 当系统中某个类的实例代表的资源是共享的,且该资源的管理需要集中控制时。例如,数据库连接池或配置管理器。
- 例子: 如果你有一个配置类
Configuration
,它读取和存储应用程序的配置信息,可能只需要一个实例来读取配置信息,避免了重复读取和管理不同的配置实例。
-
控制实例化:
- 场景: 有时候,某个类的实例化可能是昂贵的,或者系统中只允许存在一个实例。比如,大型对象的创建可能很消耗资源(例如,复杂的对象图或连接池)。
- 例子: 一个
Logger
类,用于记录日志,通常只需要一个实例来避免多个日志记录器导致的重复日志文件或性能问题。
-
全局访问点:
- 场景: 当你需要一个全局的访问点来访问某个类的功能时。单例模式可以提供一个全局访问点,确保所有使用者都访问相同的实例。
- 例子: 一个
Settings
类,用于管理应用程序的设置,通过单例模式可以确保全局范围内的设置一致性和访问简便性。
-
线程安全:
- 场景: 在多线程环境中,确保一个类只有一个实例,同时避免多个线程同时创建多个实例。单例模式可以通过适当的同步机制确保线程安全。
- 例子: 一个
ThreadSafeSingleton
类,使用双重检查锁定或其他同步机制来确保线程安全地创建单例实例。
Guide
-
先知道为什么要用单例模式;
单例设计模式的主要目的是确保一个类只有一个实例,并提供全局访问点。这对于资源共享、控制实例化、全局访问点和线程安全等场景非常有用。在很多情况下,使用 new Obj() 创建多个实例可能不符合设计需求,而单例模式可以提供更好的控制和资源管理。 -
单例模式两种创建模式的认识:
- 启动程序时马上创建;(积极型)
- 启动程序后也不创建,只在用到时才创建; (懒惰型)
-
懒惰型单例模式将遇到的多线程安全问题,所以就要学习线程安全版的懒惰型单例模式。
双重检查锁定(Double-Checked Locking): 结合了懒汉式和线程安全的优点,减少了同步开销。
枚举实现: 推荐的单例实现方式,简洁且自动支持线程安全和序列化。
What is singleton
单例模式(Singleton)是一种非常简单且容易理解的设计模式。顾名思义,单例即单一的实例,确切地讲就是指在某个系统中只存在一个实例,同时提供集中、统一的访问接口,以使系统行为保持协调一致。
更详细的解释:
单例模式是指在整个程序的生命周期内,保证一个类只能产生一个实例,确保该类的唯一性。对于一些资源管理类的场景(例如配置管理),往往需要拥有一个全局对象,这样有利于协调系统整体的行为。
singleton一词在逻辑学中指“有且仅有一个元素的集合”,这非常恰当地概括了单例的概念,也就是“一个类仅有一个实例”。