singleton pattern详解

深入understandingsingleton pattern implementation方式, threadsecurity性 and application场景

查看tutoriallist

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; } }