您的位置:首页 > 数据库

C# 数据库连接池 线程安全 单例模式 的实现

2012-04-16 16:02 281 查看
本文介绍3种线程安全模式

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: