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

【c#】线程Monitor.Wait和Monitor.Pulse使用

介绍

以一个简易版的数据库连接池的实现来说明一下
连接池的connection以队列来管理
getConnection的时候,如果队列中connection个数小于50,且暂时无可用的connection(个数为0或者peek看下头部需要先出那个元素还处于不可用状态),就新建连接并建立连接,开始一直新建到50个connection,就是_currentPoolSize =50
如果队列中connection个数大于等于50,且暂时无可用的connection(个数为0或者peek看下头部需要先出那个元素还处于不可用状态),就等着Monitor.Wait(_connectionPoolQueueLock)

returnConnection的时候,使用Monitor.Pulse(_connectionPoolQueueLock) 随机通知一个wait的线程可以继续getConnection了

using System;
using System.Collections.Generic;
using System.Data;
using System.Threading;
using Mono.Data.Sqlite;namespace demo.unity.sqlite
{public class SQLiteConnectionManager{private Queue<Tuple<SqliteConnection, DateTime>> _connectionPoolQueue;private object _connectionPoolQueueLock = new object();private const int maxPoolSize = 50;private volatile bool _disposed;private int _currentPoolSize;private readonly System.Timers.Timer _cleanupTimer = new System.Timers.Timer(10 * 60 * 1000);public SQLiteConnectionManager(){_connectionPoolQueue = new Queue<Tuple<SqliteConnection, DateTime>>(maxPoolSize);_cleanupTimer.Elapsed += _cleanupTimerElapsed;_cleanupTimer.AutoReset = true;_cleanupTimer.Start();}private void _cleanupTimerElapsed(object sender, System.Timers.ElapsedEventArgs e){lock (_connectionPoolQueueLock){while (_connectionPoolQueue.Count > 0 && (DateTime.UtcNow - _connectionPoolQueue.Peek().Item2).TotalMinutes > 15){var tup = _connectionPoolQueue.Dequeue();tup.Item1.Dispose();_currentPoolSize--;}}}private SqliteConnection _createNewConnection(SqliteConnectionStringBuilder builder){var connection = new SqliteConnection(builder.ConnectionString);connection.Open();return connection;}public SqliteConnection getConnection(SqliteConnectionStringBuilder builder){lock (_connectionPoolQueueLock){// count == 0 or queue.peek no use connectionwhile (_connectionPoolQueue.Count == 0  || _connectionPoolQueue.Peek().Item1.State != ConnectionState.Open){if (_disposed){throw new ObjectDisposedException("The DB connection pool is is already disposed");}if (_currentPoolSize < maxPoolSize){// create and open connectionvar connection = _createNewConnection(builder);_connectionPoolQueue.Enqueue( new Tuple<SqliteConnection, DateTime>(connection, DateTime.UtcNow));_currentPoolSize++;}else{Monitor.Wait(_connectionPoolQueueLock);}}return _connectionPoolQueue.Dequeue().Item1;}}public void returnConnection(SqliteConnection connection){if (connection == null){return;}lock (_connectionPoolQueueLock){_connectionPoolQueue.Enqueue(new Tuple<SqliteConnection, DateTime>(connection, DateTime.UtcNow));Monitor.Pulse(_connectionPoolQueueLock);}}public void dispose(){lock (_connectionPoolQueueLock){_disposed = true;while (_connectionPoolQueue.Count > 0){var tup  = _connectionPoolQueue.Dequeue();tup.Item1?.Dispose();_currentPoolSize--;}// wake up any waiting threadsMonitor.PulseAll(_connectionPoolQueueLock);}_cleanupTimer.Stop();_cleanupTimer.Dispose();}}
}
http://www.lryc.cn/news/186177.html

相关文章:

  • GitLab平台安装中经典安装语句含义解析
  • 湘潭大学 2023年下学期《C语言》作业0x03-循环1 XTU OJ 1094,1095,1096,1112,1113
  • 【Linux系统满足产品实时性需求】
  • 不用休眠的 Kotlin 并发:深入对比 delay() 和 sleep()
  • 在Ubuntu中批量创建用户
  • 汽车冲压车间的RFID技术设计解决方案
  • TCP 和UDP通信流程
  • Swift SwiftUI CoreData 过滤数据 1
  • 【uniapp】subnvue组件数据更新视图未更新问题
  • Unity编辑器拓展-Odin
  • 小红书婴童产业探索,解析消费者需求!
  • 离线安装mysql客户端
  • Docker 数据管理
  • 数据统计--图形报表--ApacheEcharts技术 --苍穹外卖day10
  • 【kubernetes的三种网络】
  • Java中树形菜单的实现方式(超全详解!)
  • 基于Uniswap V3的去中心化前端现货交易平台Oku正式登陆Moonbeam
  • leetcode 每日一题复盘(10.9~10.15)
  • 【云计算网络安全】DDoS 缓解解析:DDoS 攻击缓解策略、选择最佳提供商和关键考虑因素
  • 如何巧用AI智能技术,让文物不再“无人问津”?
  • 一天一八股——SSL/TLS协议
  • SpringCloud学习笔记-Eureka服务的搭建
  • css如何实现页面布局与五种实现方式
  • cv2.split函数与cv2.merge函数
  • Vue--1.7watch侦听器(监视器)
  • 序列:全序关系
  • 100M服务器能同时容纳多少人访问?
  • Javascript 笔记:函数调用与函数上下文
  • 【WebService】C#搭建的标准WebService接口,在使ESB模版作为参数无法获取参数数据
  • Sqlserver关于tempdb临时数据库文件个数的最佳实践