单例模式是一种设计模式,用于确保在应用程序中仅存在一个类的实例,并提供对该实例的全局访问点。

在单例模式中,类的构造函数被限制为仅实例化一次。如果尝试再次实例化该类,则返回现有实例的引用,而不是创建一个新实例。这可以防止多个对象同时修改应用程序的状态,从而提高了应用程序的安全性和可靠性。

单例模式常常被用于管理共享资源或状态,例如缓存、数据库连接、配置文件等。通过限制实例化次数,单例模式可以确保应用程序中只存在一个实例,从而避免资源浪费、状态不一致等问题。

在Python中,可以使用模块、装饰器或元类来实现单例模式。其中,最常见的方法是使用模块。由于在Python中,模块在解释器中只会被导入一次,因此将共享状态或资源存储在模块级别变量中,可以实现单例模式的效果。

装饰器实现单例模式(简单)

import threading

def singleton(cls):
    instances = {}
    lock = threading.Lock()  # 添加锁用于多线程安全

    def wrapper(*args, **kwargs):
        if cls not in instances:
            with lock:  # 加锁
                if cls not in instances:  # 双重检查锁定
                    instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return wrapper


@singleton
class Person:
    def __init__(self, name):
        print("执行几次?")
        self.name = name

    def get_name(self):
        return self.name

def create_person():
    per = Person("小张")
    print(per.get_name())

# 创建两个线程同时创建实例
thread1 = threading.Thread(target=create_person)
thread2 = threading.Thread(target=create_person)

thread1.start()
thread2.start()

thread1.join()
thread2.join()

# 输出结果
# 执行几次?
# 小张
# 小张

类中实现单例模式


import threading
from copy import deepcopy

'''
这段代码实现了一个单例模式,确保一个类只有一个实例对象。具体来说,它的实现原理如下:

- 在类的内部定义一个私有的类变量 `_instance` ,初始值为 None。
- 在类的 `__new__` 方法中,如果 `_instance` 已经存在(即不为 None),直接返回 `_instance`。
- 如果 `_instance` 不存在,加锁,再次判断 `_instance` 是否存在,如果不存在,调用 `super().__new__(cls, *args, **kwargs)` 创建一个新的对象,并将其赋值给 `_instance` 变量,然后返回该对象。
- 如果 `_instance` 存在,则直接返回该实例。
- 加锁保证了线程安全,避免了多个线程同时调用时可能会创建多个实例的问题。

这样,我们就可以通过多次实例化一个类,都得到同一个对象的引用。
'''


class Cache:
    _instance = None
    _lock = threading.RLock()
    _init = False

    # 单例模式 保证开启单例模式
    def __new__(cls, *args, **kwargs):
        if cls._instance:
            return cls._instance
        with cls._lock:
            if not cls._instance:
                cls._instance = super().__new__(cls, *args, **kwargs)
            return cls._instance

    def __init__(self):
        if self._init:
            return
        # 加锁  保证安全  保证实例化指向的是同样一个内存 同样一个数据 (只有第一次才会实例化 剩下的直接ruturn 了)
        self._init = True  # 将 _init 标志为 True
        self._frame_time = 0  # 当前帧时戳
        self._frame = 0

    # 添加缓存
    def set_frame(self):
        print('frame', self._frame)
        self._frame += 1

    # 获取缓存
    def get_frame(self):
        return self._frame
// JS 单例模式
let Singleton = (function() {
  let instance;

  function createInstance() {
    let object = new Object();
    return object;
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

let instance1 = Singleton.getInstance();
let instance2 = Singleton.getInstance();

console.log(instance1 === instance2); // true

作者 译文

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注