简介
单例模式(Singleton Pattern)属于创建型设计模式,这种模式只创建一个单一的类,保证一个类只有一个实例,并提供一个访问该实例的全局节点。
当您想控制实例数目,节省系统资源,并不想混用的时候,可以使用单例模式。单例有很多种实现方式,主要分为懒汉和饿汉模式,同时要通过加锁来避免线程安全。不同语言的单例实现略有差异,可以通过查看不同版本的源码来深入理解其中的差异。
不同语言设计模式源码下载:https://github.com/microwind/design-pattern
作用
- 避免全局使用的类频繁地创建与销毁。
- 保证一个类仅有一个实例,并提供一个访问它的全局访问点。
实现步骤
- 创建单例类,注意线程安全
- 返回全局唯一实例
UML
Java代码
单例实现,不同语言有很大不同,跟语言特性有关。请查看其他源码进行比较。
饿汉式(线程安全)
| |
| public class SingletonEager { |
| private String name = "SingletonEager"; |
| |
| private static final SingletonEager instance = new SingletonEager(); |
| |
| |
| private SingletonEager() { |
| |
| } |
| public static SingletonEager getInstance() { |
| return instance; |
| } |
| |
| public void run() { |
| System.out.println("SingletonEager::run() " + this.name); |
| } |
| } |
饱汉式
| |
| public class SingletonLazy { |
| |
| private static SingletonLazy instance; |
| private String name; |
| |
| private SingletonLazy() { |
| |
| } |
| |
| |
| |
| |
| public static synchronized SingletonLazy getInstance(String name) { |
| if (instance == null) { |
| instance = new SingletonLazy(); |
| instance.name = name; |
| } |
| return instance; |
| } |
| |
| public void run() { |
| System.out.println("SingletonLazy::run() " + this.name); |
| } |
| } |
静态内部类
| |
| public class SingletonInner { |
| |
| private String name; |
| |
| private SingletonInner() { |
| |
| } |
| |
| |
| |
| private static class Inner { |
| private static final SingletonInner instance = new SingletonInner(); |
| } |
| |
| |
| public static SingletonInner getInstance(String name) { |
| if (Inner.instance.name == null) { |
| Inner.instance.name = name; |
| } |
| return Inner.instance; |
| } |
| |
| public void run() { |
| System.out.println("SingletonInner::run() " + this.name); |
| } |
| } |
双重检验懒汉
| |
| public class SingletonDoubleCheck { |
| |
| |
| |
| |
| private static volatile SingletonDoubleCheck instance; |
| private String name; |
| private SingletonDoubleCheck() { |
| |
| } |
| |
| |
| public static SingletonDoubleCheck getInstance(String name) { |
| if (instance == null) { |
| |
| synchronized (SingletonDoubleCheck.class) { |
| if (instance == null) { |
| instance = new SingletonDoubleCheck(); |
| instance.name = name; |
| } |
| } |
| } |
| return instance; |
| } |
| |
| public void run() { |
| System.out.println("SingletonDoubleCheck::run() " + this.name); |
| } |
| } |
| |
测试调用
| |
| |
| |
| |
| SingletonEager singletonEager1 = SingletonEager.getInstance(); |
| SingletonEager singletonEager2 = SingletonEager.getInstance(); |
| singletonEager1.run(); |
| singletonEager2.run(); |
| |
| System.out.println("singletonEager1 == singletonEager2 ? " + String.valueOf(singletonEager1 == singletonEager2)); |
| |
| |
| |
| SingletonLazy singletonLazy1 = SingletonLazy.getInstance("singletonLazy1"); |
| SingletonLazy singletonLazy2 = SingletonLazy.getInstance("singletonLazy2"); |
| singletonLazy1.run(); |
| singletonLazy2.run(); |
| |
| |
| |
| SingletonDoubleCheck singletonDoubleCheck1 = SingletonDoubleCheck.getInstance("singletonDoubleCheck1"); |
| SingletonDoubleCheck singletonDoubleCheck2 = SingletonDoubleCheck.getInstance("singletonDoubleCheck2"); |
| singletonDoubleCheck1.run(); |
| singletonDoubleCheck2.run(); |
| |
| |
| |
| SingletonInner singletonInner1 = SingletonInner.getInstance("singletonInner1"); |
| SingletonInner singletonInner2 = SingletonInner.getInstance("singletonInner2"); |
| singletonInner1.run(); |
| singletonInner2.run(); |
Go代码
| |
| import ( |
| "fmt" |
| "sync" |
| ) |
| |
| |
| type DoubleCheckSingleton struct { |
| name string |
| } |
| |
| func (s *DoubleCheckSingleton) Run() { |
| fmt.Println("DoubleCheckSingleton::run()", s.name) |
| } |
| |
| |
| var doubleCheckSingletonInstance *DoubleCheckSingleton |
| var lock = &sync.Mutex{} |
| |
| |
| func GetDoubleCheckSingletonInstance(name string) *DoubleCheckSingleton { |
| |
| if doubleCheckSingletonInstance == nil { |
| lock.Lock() |
| defer lock.Unlock() |
| |
| if doubleCheckSingletonInstance == nil { |
| doubleCheckSingletonInstance = &DoubleCheckSingleton{} |
| doubleCheckSingletonInstance.name = name |
| } |
| } |
| |
| return doubleCheckSingletonInstance |
| } |
| |
JS版本
| |
| export class LazySingleton { |
| static instance |
| constructor(alias) { |
| this.alias = alias |
| } |
| |
| |
| |
| static getInstance(alias) { |
| if (this.instance === undefined) { |
| this.instance = new LazySingleton(alias) |
| } |
| return this.instance |
| } |
| |
| run() { |
| console.log('LazySingleton::run()', this.alias) |
| } |
| } |
Python语言
| |
| from threading import Lock, Thread |
| |
| |
| |
| class SingletonMeta(type): |
| |
| _instances = {} |
| |
| _lock: Lock = Lock() |
| |
| def __call__(cls, *args, **kwargs): |
| with cls._lock: |
| if cls not in cls._instances: |
| instance = super().__call__(*args, **kwargs) |
| cls._instances[cls] = instance |
| return cls._instances[cls] |
| |
| |
| class SingletonSafe(metaclass=SingletonMeta): |
| name: str = None |
| |
| def __init__(self, name: str) -> None: |
| self.name = name |
| |
| def run(self): |
| print('SingletonSafe::run()', self.name) |
| |
C语言
| |
| #include "func.h" |
| #include <pthread.h> |
| |
| |
| static LazySingletonSafe *lazy_singleton_safe_instance = NULL; |
| |
| void lazy_singleton_safe_run(LazySingletonSafe *singleton) |
| { |
| printf("\r\n LazySingletonSafe::run() [name=%s value=%d]", singleton->name, singleton->value); |
| } |
| |
| |
| static LazySingletonSafe *new_lazy_singleton_safe(char *name) |
| { |
| LazySingletonSafe *singleton = (LazySingletonSafe *)malloc(sizeof(LazySingletonSafe)); |
| strcpy(singleton->name, name); |
| singleton->run = &lazy_singleton_safe_run; |
| return singleton; |
| } |
| |
| |
| pthread_mutex_t singleton_lock; |
| |
| |
| LazySingletonSafe *get_lazy_singleton_safe_instance(char *name) |
| { |
| printf("\r\n get_lazy_singleton_safe_instance() [name=%s]", name); |
| if (pthread_mutex_init(&singleton_lock, NULL) != 0) |
| { |
| perror("error init mutext:"); |
| } |
| |
| |
| if (lazy_singleton_safe_instance == NULL) |
| { |
| printf("\r\n new instance [name=%s]", name); |
| pthread_mutex_lock(&singleton_lock); |
| lazy_singleton_safe_instance = new_lazy_singleton_safe(name); |
| pthread_mutex_unlock(&singleton_lock); |
| } |
| return lazy_singleton_safe_instance; |
| } |
更多语言版本
不同语言实现设计模式:https://github.com/microwind/design-pattern
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南