C# 数据库连接池 线程安全 单例模式 的实现
2012-04-16 16:02
281 查看
本文介绍3种线程安全模式
1,lock
2,Mutex
3,MethodImpl
以前写的一个MYSQL数据库连接池ConnectionPool.CS
总结:
1,上面类中使用了 主要使用了 lock 方式。
lock()是对一个对象加互斥锁,只允许一个线程访问其后大括号中语句块,直到该语句块的代码执行完才解锁,解锁后才允许其他的线程执行其语句块。
2,单例模式使用了懒汉模式。
饿汉式是在类装载的时候直接得到该类的实例,可以说是前期绑定的;懒汉式是后期绑定的,类加载的时候connPool是空的,在需要的时候才被创建且仅创建一次。饿汉式的速度快,效率高,但是耗费系统资源;懒汉式则相反。懒汉式还存在一个问题,就是后期绑定不能确保对象只能被实例化一次,这需要对指示类是否实例化的标志设置1个互斥锁,仅允许1个线程访问。这样就可以确保对象只被实例化一次。
3,单例模式的线程安全使用了 MethodImpl。
他指定了getInstance()方法同时只能被一个线程使用。
4,使用Mutex类进行同步
修改代码为:
1,lock
2,Mutex
3,MethodImpl
以前写的一个MYSQL数据库连接池ConnectionPool.CS
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Threading; using MySql.Data.MySqlClient; using System.Runtime.CompilerServices; namespace queue.service.basic { public class ConnectionPool { private Stack<MySqlConnection> pool; private const int POOL_MAX_SIZE = 20; private int current_Size = 0; private string ConnString = "";//连接字符串 private SysProperty sysProperty; private const string SYS_PROPERTY = "config\\SysProperty.xml"; private static ConnectionPool connPool; private ConnectionPool() { if (pool == null) { pool = new Stack<MySqlConnection>(); } } [MethodImpl(MethodImplOptions.Synchronized)] public static ConnectionPool getInstance() { if (connPool == null) { connPool = new ConnectionPool(); } return connPool; } public MySqlConnection getConnection() { MySqlConnection conn; lock (this) { if (pool.Count == 0) { if (current_Size < POOL_MAX_SIZE) { conn = createConnection(); current_Size++; //把conn加入到pool 中 pool.Push(conn); } else { try { Monitor.Wait(this); } catch (Exception e) { Console.WriteLine(e.Message); } } } conn = (MySqlConnection)pool.Pop(); } return conn; } private string GetConnString() { if (ConnString == "") { sysProperty = new SysProperty().LoadProperty(Path.Combine(SYS_PROPERTY)); string ip = sysProperty.getPropertyValue("databaseIP"); string dbName = sysProperty.getPropertyValue("databaseName"); string userID = sysProperty.getPropertyValue("databaseUser"); string userPwd = sysProperty.getPropertyValue("databasePassword"); ConnString = "Database=" + dbName + ";Data Source=" + ip + ";User Id=" + userID + ";Password=" + userPwd + ";" + "pooling=true;CharSet=utf8;port=3306;"; } return ConnString; } public void releaseConnection(MySqlConnection conn) { lock (this) { pool.Push(conn); Monitor.Pulse(this); } } private MySqlConnection createConnection() { lock (this) { MySqlConnection newConn = new MySqlConnection(GetConnString()); newConn.Open(); return newConn; } } } }
总结:
1,上面类中使用了 主要使用了 lock 方式。
lock()是对一个对象加互斥锁,只允许一个线程访问其后大括号中语句块,直到该语句块的代码执行完才解锁,解锁后才允许其他的线程执行其语句块。
2,单例模式使用了懒汉模式。
饿汉式是在类装载的时候直接得到该类的实例,可以说是前期绑定的;懒汉式是后期绑定的,类加载的时候connPool是空的,在需要的时候才被创建且仅创建一次。饿汉式的速度快,效率高,但是耗费系统资源;懒汉式则相反。懒汉式还存在一个问题,就是后期绑定不能确保对象只能被实例化一次,这需要对指示类是否实例化的标志设置1个互斥锁,仅允许1个线程访问。这样就可以确保对象只被实例化一次。
3,单例模式的线程安全使用了 MethodImpl。
他指定了getInstance()方法同时只能被一个线程使用。
4,使用Mutex类进行同步
修改代码为:
private static Mutex mutex = new Mutex(); public static ConnectionPool getInstance() { mutex.WaitOne(); if (connPool == null) { connPool = new ConnectionPool(); } mutex.ReleaseMutex(); return connPool; }
相关文章推荐
- C# 两行代码实现 延迟加载的单例模式(线程安全)
- 设计模式 - 线程安全的单例模式(C#)
- 设计模式之C#实现--AbstractFactory
- 趣味编程:C#中Specification模式的实现(参考答案 - 下)
- 单例模式——C++实现线程安全的单例 .
- 浅谈C#中标准Dispose模式的实现
- 一种线程安全的单例模式实现
- java实现线程安全的单利模式
- 从C#的Singleton设计模式实现看.NET Framework特性对开发者的重要性
- 第一页(服务端) :远程资源管理器 c#应用源代码,SERVICE + CLIENT 模式 可实现远程文件管理,下载功能
- C# 实现设计模式应该不拘一格
- 设计模式之C#实现--AbstractFactory
- C#中标准Dispose模式的实现
- 【设计模式】单件模式 c#与c++实现
- singleton模式四种线程安全的实现
- 单例模式——线程安全的两种实现
- 生产消费者模式实现方式和线程安全问题代码示例
- 轻量级 Lock Free 线程安全的 Queue<T> 的C#2.0实现
- c#单例模式(Singleton)的6种实现
- 用C# 实现CS模式下软件自动在线升级