单例模式适用于需要确保一个类只有一个实例对象,并且该对象需要被全局访问的情况。
- (1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件、应用配置。
- (2)控制资源的情况下,方便资源之间的互相通信。如线程池等。
实例—单例模式控制数据库连接池对象:
- 假设我们正在开发一个多线程的应用程序,其中包含一个数据库连接池对象。为了避免在多个地方重复创建数据库连接池对象,我们可以使用单例模式来确保该对象只会被创建一次,并且在多个线程之间共享一个对象。
import threading
class DatabaseConnectionPool:
instance = None
lock = threading.Lock()
def __new__(cls, *args, **kwargs):
if cls.instance is None:
with cls.lock:
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
def __init__(self):
self.connections = []
def add_connection(self, connection):
self.connections.append(connection)
def get_connection(self):
return self.connections
# 使用示例
pool = DatabaseConnectionPool()
pool.add_connection("connection1")
pool.add_connection("connection2")
def worker(i):
pool = DatabaseConnectionPool() # 多个线程共享同一个对象
pool.add_connection("connection"+str(i+1))
connection = pool.get_connection()
print(f'Thread-{threading.get_ident()} got connection:{connection}')
if __name__ == '__main__':
for i in range(4):
t = threading.Thread(target=worker(i))
t.start()
- 上述代码中,我们首先定义了一个名为 DatabaseConnectionPool 的单例类,它维护了一个连接池列表 connections,通过 addconnection 和 getconnection 方法来添加和获取连接。使用 __new 方法来创建单例对象,确保在多个线程之间只有一个实例,同时使用锁来保证线程安全。
- 然后,我们在多个线程中使用同一个连接池对象,并通过 get_connection 方法来获取连接。由于所有的线程都共享同一个连接池对象,因此在获取连接时不会出现资源浪费和重复创建对象等问题。