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. 为什么使用单例模式 创建数据库连接是一个昂贵的过程(涉及网络通信、认证等)。单例模式的连接池可以在程序启动时初始化一组连接,并在整个生命周期中重用这些连接,而不是每次请求都新建连接。同时还可…...
鸿蒙HarmonyOS 开发简介
鸿蒙开发入门教程 一、技术简介 鸿蒙操作系统(HarmonyOS)是面向万物互联时代的全场景分布式操作系统,具备分布式软总线、分布式数据管理、分布式任务调度等核心能力,能让设备间实现无缝连接与协同,为用户提供统一、流…...
2. 在后端代码中加入日志记录模块
1. 说明 日志模块基本上是每一个软件系统开发中必不可少的,主要用于持久记录一些代码运行中的输出信息,辅助编码人员进行代码调试,以及后期软件上线运行报错分析。在Python中加入日志模块比较简单,只需要借助logging和RotatingFi…...
Linux软硬链接
目录 什么是软链接?软链接的特点软链接的原理什么是硬链接硬链接的特点硬链接的原理 什么是软链接? 在Linux操作系统中,文件系统的核心概念之一是链接,包括软链接(符号链接)和硬链接。这些链接提供了访问文…...
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)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
SYN Flood的攻击原理及防御
SYN Flood的攻击原理 TCP 协议是一个可靠的、面向连接的流协议,由于 TCP 协议是建立在 IP 协议这种面向无连接的协议,所以 TCP 协议必须自己来维护连接的状态 TCP的三次握手过程 建立连接三次握手过程如下: 客户端需要发送一个 SYN包 给服…...
Javaweb数据库多表查询 内连接 外连接 子查询
内连接 外连接 左外连接,左边是全部表 表名,即使没有匹配右边的数据,也要查询出来 子查询 案例 1.没有说所有的部门,所有的员工,用内连接(隐式内连接)...
绕过 RAG 实时检索瓶颈,缓存增强生成(CAG)如何助力性能突破?
编者按: 你是否曾经遇到过这样的困扰:在开发基于 RAG 的应用时,实时检索的延迟让用户体验大打折扣?或者在处理复杂查询时,检索结果的不准确导致回答质量不尽如人意? 在当前大语言模型应用大规模落地的背景下…...
Nginx系列09(Nginx 与其他服务集成、实战项目)
目录 Nginx 与其他服务集成 实战项目 Nginx 与其他服务集成 Nginx 与 Tomcat 集成 概念:将 Nginx 作为前端代理服务器,Tomcat 作为后端应用服务器。Nginx 负责处理静态资源请求、负载均衡以及将动态请求转发给 Tomcat,Tomcat 则专注于运行…...
nvidia驱动更新,centos下安装openwebui+ollama(非docker)
查看centos内核版本 uname -a cat /etc/redhat-release下载对应的程序(这个是linux64位版本通用的) https://cn.download.nvidia.cn/tesla/550.144.03/NVIDIA-Linux-x86_64-550.144.03.run cudnn想办法自己下一下,我这里是12.x和11.x通用的…...
手机端抓包大麦网抢票协议:实现自动抢票与支付
🚀 手机端抓包大麦网抢票协议:实现自动抢票与支付 🚀 🔥 你是否还在为抢不到热门演出票而烦恼?本文将教你如何通过抓包技术获取大麦网抢票协议,并编写脚本实现自动化抢票与支付!🔥 …...
Vue3实现文件上传、下载及预览全流程详解(含完整接口调用)
文章目录 一、环境准备1.1 创建Vue3项目1.2 安装依赖1.3 配置Element Plus 二、文件上传实现2.1 基础上传组件2.2 自定义上传逻辑(Axios实现) 三、文件下载实现3.1 直接下载(已知文件URL)3.2 后端接口下载(二进制流&am…...
普通人高效使用DeepSeek指南?
李升伟 整理 DeepSeek(深度求索)作为一款智能搜索引擎或AI工具,普通人可以通过以下方式高效利用它,提升学习、工作和生活效率: --- ### **一、基础功能:精准搜索** 1. **明确需求提问** 用自然语言…...
基于JAVA+Spring+mysql_快递管理系统源码+设计文档
文末获取源码数据库文档 感兴趣的可以先收藏,有毕设问题,项目以及论文撰写等问题都可以和博主沟通,尽最大努力帮助更多的人! 摘 要 随着物流行业信息化的深入使得物流过程中货物的状态和变化透明化,现代信息化的接入使…...
《从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 “一网通办”政务服务中心建设和运行规范
黑龙江省智慧政务服务:标准规范引领服务新篇章 1. 引言 在数字化转型的大潮中,智慧政务服务作为提升政府服务效能、优化营商环境、增强民众获得感的重要手段,正受到越来越多的关注。黑龙江省紧跟时代步伐,出台了一系列智慧政务服…...
基于SpringBoot的美妆购物网站系统设计与实现现(源码+SQL脚本+LW+部署讲解等)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
如何评估所选择的PHP后端框架的性能?
大家在选择PHP后端框架的时候,如果想评估其性能如何,能不能扛得住你的项目?可以根据以下几点进行分析,帮助大家选择到更符合自己心目中的PHP后端框架。 1. 基准测试 基准测试是评估框架性能的基础方法,主要通过模拟高…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
