• 单例模式适用于需要确保一个类只有一个实例对象,并且该对象需要被全局访问的情况。

      • (1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件、应用配置。
      • (2)控制资源的情况下,方便资源之间的互相通信。如线程池等。
    • 实例—单例模式控制数据库连接池对象:

      • 假设我们正在开发一个多线程的应用程序,其中包含一个数据库连接池对象。为了避免在多个地方重复创建数据库连接池对象,我们可以使用单例模式来确保该对象只会被创建一次,并且在多个线程之间共享一个对象。
    1. import threading
    2. class DatabaseConnectionPool:
    3. instance = None
    4. lock = threading.Lock()
    5. def __new__(cls, *args, **kwargs):
    6. if cls.instance is None:
    7. with cls.lock:
    8. if cls.instance is None:
    9. cls.instance = super().__new__(cls)
    10. return cls.instance
    11. def __init__(self):
    12. self.connections = []
    13. def add_connection(self, connection):
    14. self.connections.append(connection)
    15. def get_connection(self):
    16. return self.connections
    17. # 使用示例
    18. pool = DatabaseConnectionPool()
    19. pool.add_connection("connection1")
    20. pool.add_connection("connection2")
    21. def worker(i):
    22. pool = DatabaseConnectionPool() # 多个线程共享同一个对象
    23. pool.add_connection("connection"+str(i+1))
    24. connection = pool.get_connection()
    25. print(f'Thread-{threading.get_ident()} got connection:{connection}')
    26. if __name__ == '__main__':
    27. for i in range(4):
    28. t = threading.Thread(target=worker(i))
    29. t.start()

    单例模式应用场景 - 图1

    • 上述代码中,我们首先定义了一个名为 DatabaseConnectionPool 的单例类,它维护了一个连接池列表 connections,通过 addconnection 和 getconnection 方法来添加和获取连接。使用 __new 方法来创建单例对象,确保在多个线程之间只有一个实例,同时使用锁来保证线程安全。
    • 然后,我们在多个线程中使用同一个连接池对象,并通过 get_connection 方法来获取连接。由于所有的线程都共享同一个连接池对象,因此在获取连接时不会出现资源浪费和重复创建对象等问题。