当前位置: 首页 > 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;主要通过模拟高…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...