单例模式的核心特征是:** 保证一个类仅有一个实例**

单例模式的核心特征是:** 保证一个类仅有一个实例** 单例模式的核心特征是B. 保证一个类仅有一个实例单例模式Singleton Pattern是一种创建型设计模式其核心目标是确保某一个类在整个应用程序生命周期中有且仅有一个实例并提供一个全局访问点。虽然延迟加载如懒汉式实现是单例的一种常见实现策略但并非所有单例都必须延迟加载例如饿汉式在类加载时即创建实例工厂模式、继承复用等则属于其他设计模式或机制与单例本质无关。# Python 示例线程安全的懒汉式单例使用双重检查锁importthreadingclassSingleton:_instanceNone_lockthreading.Lock()def__new__(cls):ifcls._instanceisNone:withcls._lock:ifcls._instanceisNone:cls._instancesuper().__new__(cls)returncls._instance“饿汉式”和“懒汉式”是单例模式的两种经典实现方式主要区别在于实例创建的时机、线程安全性、资源占用与初始化开销维度饿汉式Eager Initialization懒汉式Lazy Initialization创建时机类加载时立即创建实例JVM 加载类或 Python 导入模块时第一次调用获取实例方法如getInstance()时才创建线程安全天然线程安全实例早已存在无竞态非同步版本不安全需加锁如synchronized/threading.Lock保证安全资源消耗无论是否使用都占用内存可能造成资源浪费按需创建节省内存尤其适用于重量级对象或低频使用场景初始化开销启动时即执行初始化逻辑可能延长启动时间首次访问时延迟初始化启动快但首次调用有延迟实现简洁性实现简单无同步开销实现稍复杂需处理双重检查锁 DCL 等细节✅ 示例对比Java 风格伪代码饿汉式publicclassSingleton{privatestaticfinalSingletoninstancenewSingleton();// 类加载即创建privateSingleton(){}publicstaticSingletongetInstance(){returninstance;}}懒汉式双重检查锁publicclassSingleton{privatestaticvolatileSingletoninstance;privateSingleton(){}publicstaticSingletongetInstance(){if(instancenull){synchronized(Singleton.class){if(instancenull){instancenewSingleton();}}}returninstance;}}⚠️ 补充Python 中因 GIL 和模块机制常采用更简洁方式如模块单例或装饰器但概念本质一致。在懒汉式单例的双重检查锁Double-Checked Locking, DCL中volatile关键字Java的作用是禁止指令重排序并保证可见性而 Python 中不使用volatile语言无此关键字而是依赖threading.Lock保证原子性与同步threading.local则用于线程局部存储、与 DCL 无关此处题干有误需澄清。✅ Java 中volatile的必要性核心原因DCL 的经典写法publicclassSingleton{privatestaticvolatileSingletoninstance;// ← 必须 volatileprivateSingleton(){}publicstaticSingletongetInstance(){if(instancenull){// 第一次检查synchronized(Singleton.class){if(instancenull){// 第二次检查instancenewSingleton();// ← 问题发生在此行}}}returninstance;}}⚠️若无volatile可能发生“部分初始化”问题new Singleton()包含三步非原子分配内存空间在内存中初始化对象调用构造函数将instance引用指向该内存地址即赋值。JVM 和 CPU 可能对步骤 2 和 3 进行指令重排序只要不改变单线程语义。于是可能出现线程 A 执行到步骤 3instance已非 null但步骤 2 尚未完成对象字段仍为默认值此时线程 B 进入第一个if (instance null)→ 判定为非 null直接返回一个未完全初始化的对象→ 导致NullPointerException或逻辑错误。✅volatile的两大保障禁止重排序禁止 JVM 将instance new Singleton()的赋值操作与其构造过程重排序可见性保证当一个线程写入volatile变量其他线程读取时能立即看到最新值含其所有之前写入的内存状态。❌ Python 中不存在volatile也不应混淆threading.localPython没有volatile关键字且 CPython 的 GIL 并不能替代同步机制来解决 DCL 的重排序问题GIL 仅保护字节码级原子性不防止对象构造过程中的内存可见性问题threading.local()提供的是线程局部存储每个线程独立副本它完全违背单例“全局唯一”的语义不可用于实现单例与 DCL 无关✅ Python 实现线程安全懒汉单例的正确方式是使用threading.Lock或threading.once/模块级锁确保__new__中实例创建的原子性例如importthreadingclassSingleton:_instanceNone_lockthreading.Lock()def__new__(cls):ifcls._instanceisNone:withcls._lock:ifcls._instanceisNone:cls._instancesuper().__new__(cls)returncls._instance此处Lock保证了临界区的互斥执行天然避免了重排序引发的竞态——因为构造和赋值被包裹在同一个原子锁内其他线程无法在中间状态读取到未完成对象。总结对比语言关键机制作用Javavolatile字段 DCL防止重排序 保证可见性使 DCL 安全有效Pythonthreading.Lock必需通过互斥锁强制串行化创建过程从根源上消除竞态无需volatile语言不支持也不适用 注意题干中提到的threading.local是常见误解——它用于隔离线程数据不是单例实现手段更不参与 DCL。