当前位置: 首页 > news >正文

python中单例模式应用

数据库连接池单例模式
 

1. 为什么使用单例模式

创建数据库连接是一个昂贵的过程(涉及网络通信、认证等)。单例模式的连接池可以在程序启动时初始化一组连接,并在整个生命周期中重用这些连接,而不是每次请求都新建连接。同时还可以控制连接数量,防止资源耗尽。


2.代码

下面这段代码实现了一个数据库连接池,并且通过单例模式确保整个程序中只有一个连接池实例,包含扩容机制。避免频繁创建和销毁数据库连接,通过单例复用连接池:

通过单例模式确保全局只有一个连接池实例。
使用线程锁和条件变量实现线程安全,处理多线程环境下的并发访问。
提供连接的创建、获取、归还和关闭功能。
通过多线程测试验证连接池的并发性能。

import pymysql
import threading
from pymysql import Errorclass DatabasePool:_instance = Nonedef __new__(cls):if not cls._instance:cls._instance = super().__new__(cls)# 数据库配置cls._instance.config = {'host': 'localhost','user': 'root','password': '111111','database': 'test','charset': 'utf8mb4','cursorclass': pymysql.cursors.DictCursor}# 使用可重入锁和条件变量cls._instance.lock = threading.RLock()cls._instance.condition = threading.Condition(cls._instance.lock)cls._instance.max_connections = 10cls._instance.connections = []  # 未使用的连接cls._instance.in_use = set()   # 正在使用的连接cls._instance.init_pool()return cls._instance    # 返回唯一的连接池实例def init_pool(self):"""初始化连接池(线程安全)"""with self.lock:for _ in range(self.max_connections):self.add_connection()def create_connection(self):"""创建单个数据库连接(无需加锁)"""try:conn = pymysql.connect(**self.config)print(f"成功创建连接:{conn._sock.getsockname()}")return connexcept Error as e:print(f"连接创建失败: {e}")return Nonedef add_connection(self):"""向连接池添加连接(线程安全)"""if len(self.connections) + len(self.in_use) < self.max_connections:conn = self.create_connection()if conn:self.connections.append(conn)def get_connection(self):"""获取连接(线程安全)"""with self.condition:while not self.connections:if len(self.in_use) < self.max_connections:self.add_connection()else:print("连接池已满,等待连接归还...")self.condition.wait()  # 等待连接归还conn = self.connections.pop()self.in_use.add(conn)print(f"获取连接:{conn._sock.getsockname()}")return conndef release_connection(self, conn):"""归还连接(线程安全)"""with self.condition:if conn in self.in_use:self.in_use.remove(conn)if conn.open:self.connections.append(conn)print(f"归还连接:{conn._sock.getsockname()}")self.condition.notify()  # 通知等待的线程else:print("警告:连接已关闭,直接丢弃")def close_pool(self):"""关闭所有连接(线程安全)"""with self.lock:for conn in self.connections + list(self.in_use):if conn.open:conn.close()self.connections.clear()self.in_use.clear()print("所有数据库连接已关闭")# 多线程测试示例
if __name__ == "__main__":import concurrent.futuresdef worker(thread_id):pool = DatabasePool()conn = pool.get_connection()try:with conn.cursor() as cursor:cursor.execute("SELECT SLEEP(1)")  # 模拟耗时操作print(f"线程 {thread_id} 执行查询")finally:pool.release_connection(conn)# 创建连接池pool = DatabasePool()# 使用15个线程并发测试,超过最大连接数with concurrent.futures.ThreadPoolExecutor(max_workers=15) as executor:futures = [executor.submit(worker, i) for i in range(15)]for future in concurrent.futures.as_completed(futures):future.result()pool.close_pool()

3. 核心:__new__ 方法

class DatabasePool:_instance = None  # 类变量,用于保存唯一的实例def __new__(cls):if not cls._instance:cls._instance = super().__new__(cls)# 数据库配置cls._instance.config = {'host': 'localhost','user': 'root','password': '111111','database': 'test','charset': 'utf8mb4','cursorclass': pymysql.cursors.DictCursor}# 使用可重入锁和条件变量cls._instance.lock = threading.RLock()cls._instance.condition = threading.Condition(cls._instance.lock)cls._instance.max_connections = 10cls._instance.connections = []  # 未使用的连接cls._instance.in_use = set()   # 正在使用的连接cls._instance.init_pool()return cls._instance    # 返回唯一的连接池实例
  • 作用:确保无论创建多少次 DatabasePool(),都只会生成同一个实例
  • 示例
    pool1 = DatabasePool()  # 第一次创建,初始化连接池
    pool2 = DatabasePool()  # 直接返回 pool1 的实例
    print(pool1 is pool2)   # 输出 True

3. 总结

我们可以把连接池想象成一个共享铅笔盒(全班共享)

  • :管理员(锁)确保一次只有一个人能拿铅笔。
  • 连接:铅笔盒里的铅笔(初始10支)。
  • 动态扩容:当铅笔用完时,管理员临时制作新铅笔。
  • 归还机制:用完后必须归还,否则其他人无法使用。

相关文章:

python中单例模式应用

数据库连接池单例模式 1. 为什么使用单例模式 创建数据库连接是一个昂贵的过程&#xff08;涉及网络通信、认证等&#xff09;。单例模式的连接池可以在程序启动时初始化一组连接&#xff0c;并在整个生命周期中重用这些连接&#xff0c;而不是每次请求都新建连接。同时还可…...

鸿蒙HarmonyOS 开发简介

鸿蒙开发入门教程 一、技术简介 鸿蒙操作系统&#xff08;HarmonyOS&#xff09;是面向万物互联时代的全场景分布式操作系统&#xff0c;具备分布式软总线、分布式数据管理、分布式任务调度等核心能力&#xff0c;能让设备间实现无缝连接与协同&#xff0c;为用户提供统一、流…...

2. 在后端代码中加入日志记录模块

1. 说明 日志模块基本上是每一个软件系统开发中必不可少的&#xff0c;主要用于持久记录一些代码运行中的输出信息&#xff0c;辅助编码人员进行代码调试&#xff0c;以及后期软件上线运行报错分析。在Python中加入日志模块比较简单&#xff0c;只需要借助logging和RotatingFi…...

Linux软硬链接

目录 什么是软链接&#xff1f;软链接的特点软链接的原理什么是硬链接硬链接的特点硬链接的原理 什么是软链接&#xff1f; 在Linux操作系统中&#xff0c;文件系统的核心概念之一是链接&#xff0c;包括软链接&#xff08;符号链接&#xff09;和硬链接。这些链接提供了访问文…...

Kali换源

【刚忘了】 下面这个 里面的一删放就好了 deb http://mirrors.aliyun.com/kali kali-rolling main non-free contribdeb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contrib...

Java 大视界 -- Java 大数据机器学习模型的可解释性增强技术与应用(107)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

SYN Flood的攻击原理及防御

SYN Flood的攻击原理 TCP 协议是一个可靠的、面向连接的流协议&#xff0c;由于 TCP 协议是建立在 IP 协议这种面向无连接的协议&#xff0c;所以 TCP 协议必须自己来维护连接的状态 TCP的三次握手过程 建立连接三次握手过程如下&#xff1a; 客户端需要发送一个 SYN包 给服…...

Javaweb数据库多表查询 内连接 外连接 子查询

内连接 外连接 左外连接&#xff0c;左边是全部表 表名&#xff0c;即使没有匹配右边的数据&#xff0c;也要查询出来 子查询 案例 1.没有说所有的部门&#xff0c;所有的员工&#xff0c;用内连接&#xff08;隐式内连接&#xff09;...

绕过 RAG 实时检索瓶颈,缓存增强生成(CAG)如何助力性能突破?

编者按&#xff1a; 你是否曾经遇到过这样的困扰&#xff1a;在开发基于 RAG 的应用时&#xff0c;实时检索的延迟让用户体验大打折扣&#xff1f;或者在处理复杂查询时&#xff0c;检索结果的不准确导致回答质量不尽如人意&#xff1f; 在当前大语言模型应用大规模落地的背景下…...

Nginx系列09(Nginx 与其他服务集成、实战项目)

目录 Nginx 与其他服务集成 实战项目 Nginx 与其他服务集成 Nginx 与 Tomcat 集成 概念&#xff1a;将 Nginx 作为前端代理服务器&#xff0c;Tomcat 作为后端应用服务器。Nginx 负责处理静态资源请求、负载均衡以及将动态请求转发给 Tomcat&#xff0c;Tomcat 则专注于运行…...

nvidia驱动更新,centos下安装openwebui+ollama(非docker)

查看centos内核版本 uname -a cat /etc/redhat-release下载对应的程序&#xff08;这个是linux64位版本通用的&#xff09; https://cn.download.nvidia.cn/tesla/550.144.03/NVIDIA-Linux-x86_64-550.144.03.run cudnn想办法自己下一下&#xff0c;我这里是12.x和11.x通用的…...

手机端抓包大麦网抢票协议:实现自动抢票与支付

&#x1f680; 手机端抓包大麦网抢票协议&#xff1a;实现自动抢票与支付 &#x1f680; &#x1f525; 你是否还在为抢不到热门演出票而烦恼&#xff1f;本文将教你如何通过抓包技术获取大麦网抢票协议&#xff0c;并编写脚本实现自动化抢票与支付&#xff01;&#x1f525; …...

Vue3实现文件上传、下载及预览全流程详解(含完整接口调用)

文章目录 一、环境准备1.1 创建Vue3项目1.2 安装依赖1.3 配置Element Plus 二、文件上传实现2.1 基础上传组件2.2 自定义上传逻辑&#xff08;Axios实现&#xff09; 三、文件下载实现3.1 直接下载&#xff08;已知文件URL&#xff09;3.2 后端接口下载&#xff08;二进制流&am…...

普通人高效使用DeepSeek指南?

李升伟 整理 DeepSeek&#xff08;深度求索&#xff09;作为一款智能搜索引擎或AI工具&#xff0c;普通人可以通过以下方式高效利用它&#xff0c;提升学习、工作和生活效率&#xff1a; --- ### **一、基础功能&#xff1a;精准搜索** 1. **明确需求提问** 用自然语言…...

基于JAVA+Spring+mysql_快递管理系统源码+设计文档

文末获取源码数据库文档 感兴趣的可以先收藏&#xff0c;有毕设问题&#xff0c;项目以及论文撰写等问题都可以和博主沟通&#xff0c;尽最大努力帮助更多的人&#xff01; 摘 要 随着物流行业信息化的深入使得物流过程中货物的状态和变化透明化&#xff0c;现代信息化的接入使…...

《从0到1:用Python在鸿蒙系统开发安防图像分类AI功能》

在人工智能与移动应用深度融合的当下,类目标签AI功能成为众多行业提升效率和用户体验的关键技术。本文聚焦于HarmonyOS NEXT API 12及以上版本,以图像分类在智能家居安防领域的应用为例,为开发者详细阐述如何利用Python开发类目标签AI功能,助力鸿蒙技术在该领域的创新应用。…...

第十四届蓝桥杯大赛软件赛国赛C/C++大学C组

A 【跑步计划——日期问题】-CSDN博客 B 【残缺的数字】-CSDN博客 C 题目 代码 #include <bits/stdc.h> using namespace std;void change(int &x) {int sum 0, t x;while(t){sum t % 10;t / 10;}x - sum; } int main() {int n;cin >> n;int ans 0;…...

黑龙江省地标-DB31/T 862-2021 “一网通办”政务服务中心建设和运行规范

黑龙江省智慧政务服务&#xff1a;标准规范引领服务新篇章 1. 引言 在数字化转型的大潮中&#xff0c;智慧政务服务作为提升政府服务效能、优化营商环境、增强民众获得感的重要手段&#xff0c;正受到越来越多的关注。黑龙江省紧跟时代步伐&#xff0c;出台了一系列智慧政务服…...

基于SpringBoot的美妆购物网站系统设计与实现现(源码+SQL脚本+LW+部署讲解等)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

如何评估所选择的PHP后端框架的性能?

大家在选择PHP后端框架的时候&#xff0c;如果想评估其性能如何&#xff0c;能不能扛得住你的项目&#xff1f;可以根据以下几点进行分析&#xff0c;帮助大家选择到更符合自己心目中的PHP后端框架。 1. 基准测试 基准测试是评估框架性能的基础方法&#xff0c;主要通过模拟高…...

s10_团队协议设计:为什么多智能体协作不能只靠发消息

团队协议设计&#xff1a;为什么多智能体协作不能只靠发消息 很多人第一次做多智能体协作时&#xff0c;直觉都是&#xff1a;只要能让队友之间互相发消息&#xff0c;团队就算搭起来了。 这个想法不算错&#xff0c;但只对了一半。 s09 确实已经把“常驻队友 文件邮箱 线…...

实战演练:基于快马AI打造Ubuntu OpenClaw颜色分拣机器人应用

实战演练&#xff1a;基于快马AI打造Ubuntu OpenClaw颜色分拣机器人应用 最近在研究机器人抓取和分拣的应用场景&#xff0c;正好用InsCode(快马)平台尝试了一个OpenClaw颜色分拣机器人的项目。整个过程比我预想的要顺利很多&#xff0c;特别是平台提供的AI辅助功能&#xff0…...

为什么说C#是Windows开发者的瑞士军刀?WPF、ASP.NET实战解析

为什么说C#是Windows开发者的瑞士军刀&#xff1f;WPF、ASP.NET实战解析 在Windows生态系统中&#xff0c;C#始终保持着不可替代的地位。这门由微软精心设计的语言&#xff0c;从2000年诞生至今&#xff0c;已经发展成为企业级应用、桌面程序和Web服务的全能选手。尤其对于Win…...

Agent RAG 底层核心难点

Agent 1. 任务规划与拆解 (Reasoning & Decomposition) 递归深度失控&#xff1a;任务拆得太细导致逻辑迷失&#xff0c;或拆得太粗无法执行。目标漂移 (Goal Drift)&#xff1a;长流程中 Agent 忘记了最初的最终目标。不可逆决策风险&#xff1a;在缺乏“回滚”机制的现实…...

一键隐藏桌面图标任务栏的实用工具

软件介绍 AutoDesktop是一个专门管理桌面图标显示与隐藏的小工具。它的作用很简单&#xff1a;一键把桌面上乱七八糟的图标和底部的任务栏全都藏起来&#xff0c;还你一个干干净净的桌面。 体积小巧运行轻量 整个软件才40K大小&#xff0c;真的非常小。双击运行后会自动关闭…...

PyTorch系列 —— 深入解析nn.Module与nn.Linear的魔法调用机制

1. 从魔法调用开始&#xff1a;为什么m(input)能直接计算&#xff1f; 第一次看到m nn.Linear(20, 30)后面跟着output m(input)这种写法时&#xff0c;我盯着屏幕愣了三秒——这明明是个类实例&#xff0c;怎么可以直接当函数用&#xff1f;后来才发现&#xff0c;这正是PyTo…...

从手动15秒到自动0.8秒:米哈游游戏扫码登录的智能革命

从手动15秒到自动0.8秒&#xff1a;米哈游游戏扫码登录的智能革命 【免费下载链接】MHY_Scanner MHY扫码登录器&#xff0c;支持从直播流抢码。 项目地址: https://gitcode.com/gh_mirrors/mh/MHY_Scanner 在直播抢码、多账号切换的激烈竞争中&#xff0c;你是否还在为手…...

从‘套娃’结构到SOTA效果:我是如何用U2-Net搞定商品抠图与海报生成的

从‘套娃’结构到SOTA效果&#xff1a;我是如何用U2-Net搞定商品抠图与海报生成的 去年双十一大促前&#xff0c;我们电商团队遇到了一个棘手问题&#xff1a;每天新增的上万张商品图需要快速去除背景&#xff0c;用于生成营销海报。传统Photoshop手动处理每张图需要5-10分钟&a…...

LabView实战:高效实现float到十六进制的精准转换VI设计

1. 为什么需要float到十六进制的精准转换&#xff1f; 在工业自动化和测试测量领域&#xff0c;我们经常需要处理各种传感器采集的浮点数据。比如温度传感器返回的25.6℃、压力传感器检测的101.325kPa&#xff0c;这些数据在LabView中通常以float类型存储。但在某些特殊场景下&…...

语音转文字神器!Speech Seaco Paraformer WebUI详细使用指南

语音转文字神器&#xff01;Speech Seaco Paraformer WebUI详细使用指南 1. 为什么你需要这个语音识别工具 在日常工作和学习中&#xff0c;我们经常遇到需要将语音内容转换为文字的场景。无论是会议记录、采访整理&#xff0c;还是视频字幕制作&#xff0c;传统的手动听写方…...