singleton pattern详解
singleton pattern is acreation型design模式, 它确保一个class只 has 一个instance, 并providing一个全局访问点来访问这个instance. singleton pattern in practicalDevelopmentin非常常用, 特别 is in 需要全局唯一instance 场景 under , such asconfigurationmanagement, log记录, datalibrary连接池etc..
singleton pattern concepts
singleton pattern core思想 is :
- 确保一个class只 has 一个instance
- providing一个全局访问点来访问这个instance
- 防止 out 部直接instance化该class
singleton pattern 特点
- 唯一性: 确保一个class只 has 一个instance
- 全局访问: providing一个全局访问点
- latency初始化: 可以按需creationinstance (懒加载)
- threadsecurity: in many threadenvironment under 确保instance 唯一性
singleton pattern implementation方式
1. 饿汉式
饿汉式 in class加载时就creationinstance, ensuredthreadsecurity, 但可能会导致不必要 memory占用.
// 饿汉式singleton pattern
class SingletonEager {
// in class加载时就creationinstance
private static final SingletonEager instance = new SingletonEager();
// 私 has constructmethod, 防止 out 部instance化
private SingletonEager() {
}
// providing全局访问点
public static SingletonEager getInstance() {
return instance;
}
}
2. 懒汉式
懒汉式 in 第一次using时才creationinstance, implementation了latency加载, 但需要考虑threadsecurityissues.
// 懒汉式singleton pattern (非threadsecurity)
class SingletonLazy {
// 初始化 for null, latency加载
private static SingletonLazy instance;
// 私 has constructmethod
private SingletonLazy() {
}
// providing全局访问点
public static SingletonLazy getInstance() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
}
// 懒汉式singleton pattern (threadsecurity, usingsynchronized)
class SingletonLazySafe {
private static SingletonLazySafe instance;
private SingletonLazySafe() {
}
// usingsynchronized确保threadsecurity
public static synchronized SingletonLazySafe getInstance() {
if (instance == null) {
instance = new SingletonLazySafe();
}
return instance;
}
}
3. 双重checklock (DCL)
双重checklock结合了懒加载 and threadsecurity 优点, through两次check and volatile关键字确保threadsecurity and performance.
// 双重checklocksingleton pattern
class SingletonDCL {
// usingvolatile关键字确保可见性
private static volatile SingletonDCL instance;
private SingletonDCL() {
}
public static SingletonDCL getInstance() {
// 第一次check, 避免不必要 synchronization
if (instance == null) {
synchronized (SingletonDCL.class) {
// 第二次check, 确保只creation一个instance
if (instance == null) {
instance = new SingletonDCL();
}
}
}
return instance;
}
}
4. 静态 in 部class
静态 in 部class利用Javaclass加载mechanism确保threadsecurity, 同时implementation了latency加载.
// 静态 in 部classsingleton pattern
class SingletonStaticInner {
// 私 has constructmethod
private SingletonStaticInner() {
}
// 静态 in 部class
private static class SingletonHolder {
private static final SingletonStaticInner INSTANCE = new SingletonStaticInner();
}
// providing全局访问点
public static SingletonStaticInner getInstance() {
return SingletonHolder.INSTANCE;
}
}
5. 枚举单例
枚举单例 is Javain最 simple , 最security 单例implementation方式, 利用枚举 features确保threadsecurity and 防止反射攻击.
// 枚举singleton pattern
enum SingletonEnum {
// 唯一instance
INSTANCE;
// 枚举可以 has 成员variable and method
private String data;
public void setData(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
// using方式
// SingletonEnum.INSTANCE.setData("test");
// String data = SingletonEnum.INSTANCE.getData();
singleton pattern threadsecurity性
in many threadenvironment under , singleton pattern implementation需要考虑threadsecurityissues, 不同implementation方式 threadsecurityfeaturessuch as under :
| implementation方式 | threadsecurity | latency加载 | performance | security性 |
|---|---|---|---|---|
| 饿汉式 | is | 否 | high | in |
| 懒汉式 (非synchronization) | 否 | is | high | low |
| 懒汉式 (synchronization) | is | is | low | in |
| 双重checklock | is | is | high | in |
| 静态 in 部class | is | is | high | high |
| 枚举单例 | is | 否 | high | 最 high |
threadsecurityNotes
- 懒汉式 (非synchronization) in many threadenvironment under 可能creation many 个instance
- usingsynchronized关键字会影响performance
- 双重checklock需要usingvolatile关键字确保可见性
- 反射 and 序列化可能破 bad singleton pattern 唯一性
singleton pattern application场景
singleton pattern in 以 under 场景in特别适用:
1. configurationmanagement
configurationmanagement器需要全局唯一, 确保所 has componentusing相同 configuration.
2. log记录
log记录器通常需要全局唯一, 确保log consistency and 顺序.
3. datalibrary连接池
datalibrary连接池需要全局唯一, 避免creation过 many 连接.
4. thread池
thread池需要全局唯一, 统一managementthreadresource.
5. cache
cachemanagement器需要全局唯一, 确保cache consistency.
6. toolclass
一些toolclass只需要一个instance, 避免重复creation.
singleton pattern Pros and Cons
优点
- 确保一个class只 has 一个instance, 节省systemresource
- providing全局访问点, 方便using
- 避免重复creationobject, improvingperformance
- 可以控制instance creation时机 (懒加载)
缺点
- 违反单一职责principles, 既负责creationinstance又负责业务逻辑
- 可能导致memory泄漏, 因 for 单例instance会一直存 in
- 不利于单元test, 因 for 单例 is 全局status
- 可能被反射 and 序列化破 bad
实践case: singleton pattern application
case: configurationmanagement器
fake设你需要design一个configurationmanagement器, 需要考虑以 under requirements:
- configurationmanagement器需要全局唯一
- configuration需要 from file加载, 加载过程比较耗时
- 需要supportrun时modifyconfiguration
- 需要threadsecurity
usingsingleton patternimplementationconfigurationmanagement器:
// configurationmanagement器单例
class Configmanagementr {
// using双重checklockimplementationthreadsecurity 懒加载
private static volatile Configmanagementr instance;
private Map configs;
private Configmanagementr() {
// 私 has constructmethod, 加载configuration
loadConfigs();
}
private void loadConfigs() {
// from file加载configuration (mock)
configs = new HashMap<>();
configs.put("database.url", "jdbc:mysql://localhost:3306/db");
configs.put("database.username", "root");
configs.put("database.password", "password");
configs.put("app.port", "8080");
System.out.println("Configs loaded from file");
}
public static Configmanagementr getInstance() {
if (instance == null) {
synchronized (Configmanagementr.class) {
if (instance == null) {
instance = new Configmanagementr();
}
}
}
return instance;
}
public String getConfig(String key) {
return configs.get(key);
}
public void setConfig(String key, String value) {
configs.put(key, value);
}
public void reloadConfigs() {
loadConfigs();
}
}
// using方式
// Configmanagementr configmanagementr = Configmanagementr.getInstance();
// String dbUrl = configmanagementr.getConfig("database.url");
互动练习
练习1: singleton patternimplementation
请implementation一个threadsecurity singleton pattern, 要求:
- supportlatency加载
- threadsecurity
- performance良 good
- 防止反射攻击
练习2: singleton patternapplication
请design一个log记录器, usingsingleton patternimplementation, 要求:
- 全局唯一 log记录器
- support不同级别 log (INFO, DEBUG, ERROR)
- supportlogfile输出
- threadsecurity
练习3: singleton patternanalysis
analysis以 under code is 否 is threadsecurity singleton pattern, such as果不 is , 请指出issues并给出improvementsolutions:
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}