C# 數據庫連接池 線程安全 單例模式 的實現


本文介紹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;
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM