对象池化技术相关
在系统设计中,经常会使用“池”的概念。比如数据库连接池,socket连接池,线程池,组件队列。“池”可以节省对象重复创建和初始化所耗费 的时间,可以简化对象获取和使用的过程。对于那些被系统频繁请求和使用的对象,如果使用这种机制,可以使系统性能得到很大提高。特别象数据库连接这种对 象,客户端与数据库服务器端建立连接时,是比较慢的,如果每次进行数据库操作,都要先进行数据库连接,系统效率将非常低下。
“池”的概念就是将被使用的对象事先创建好,保存在列表中,供客户端取用。当客户端取得一个对象时,这个对象就已经是按照特定上下文环境初始化好,马上即 可使用的了。当客户端使用完毕,需要将对象归还给“池”,最后,在系统生命期结束时,由“池”统一释放这些对象。从另一个概念上来说,这也是一种“以空间 换时间”的做法,我们在内存中保存一系列整装待命的对象,供人随时差遣。与系统效率相比,这些对象所占用的内存空间太微不足道了。
“池”的结构是通用的,就是不管他里面保存的是哪一种对象,他的工作方法都基本不变。无非是初始化一系列对象,然后提供一个获取可用对象,一个归还对象的接口。
// // 对象池 // // using System; using System.Collections.Generic; using System.Text; using System.Timers; using System.Collections; namespace objectPool { /// <summary> /// 对象池 /// </summary> /// <typeparam name="T">对象类型</typeparam> abstract class objectPool<T> { /// <summary> /// 最后取出对象时间 /// </summary> private long longLastCheckOut = 0; /// <summary> /// 记录当前正在使用对象Hashtable /// </summary> private static Hashtable objLocked; /// <summary> /// 记录全部空闲及可用对象Hashtable /// </summary> private static Hashtable objUnLocked; /// <summary> /// 检查所有空闲及可用对象时间间隔:60秒(用于垃圾回收) /// </summary> private static long CLEANINTERVAL = 60 * 1000; /// <summary> /// 初始化成员变量 /// </summary> static objectPool() { // 实例化对象 objLocked = Hashtable.Synchronized(new Hashtable()); objUnLocked = Hashtable.Synchronized(new Hashtable()); } /// <summary> /// 创建一个新的对象 /// </summary> /// <returns>对象实例</returns> protected abstract T Create(); /// <summary> /// 检查特定对象有效性 /// </summary> /// <param name="t">对象实例</param> /// <returns>是否有效 true or false</returns> protected abstract bool ValiDate(T t); /// <summary> /// 删除对象 /// </summary> /// <param name="t">对象实例</param> protected abstract void Expire(T t); /// <summary> /// 构造函数 /// </summary> internal objectPool() { // 取得现在时间 longLastCheckOut = DateTime.Now.Ticks; // 实例化一个Timer对象 Timer timer = new Timer(); // 设置时间间隔 timer.Interval = CLEANINTERVAL; timer.Enabled = true; // 到达时间间隔发生(垃圾回收) timer.Elapsed += delegate { lock (this) { long longNow = DateTime.Now.Ticks; try { foreach (DictionaryEntry entry in objUnLocked) { T t = (T)entry.Key; // 超出垃圾回收时间间隔 if (longNow - (long)objUnLocked[t] > CLEANINTERVAL) { // 从可用对象中排除 objUnLocked.Remove(t); // 删除对象 Expire(t); } } } catch (Exception) { } } }; } /// <summary> /// 从池中获取对象 /// </summary> /// <returns>对象实例</returns> internal T GetObjectFromPool() { long longNow = DateTime.Now.Ticks; longLastCheckOut = longNow; T t; lock (this) { try { foreach (DictionaryEntry entry in objUnLocked) { t = (T)entry.Key; // 如果对象有效 if (ValiDate(t)) { // 设置为非空闲对象 objUnLocked.Remove(t); objLocked.Add(t, longNow); return t; } else { // 删除对象 objUnLocked.Remove(t); Expire(t); } } } catch (Exception) { } // 新创建对象 t = Create(); // 设置为正在使用对象 objLocked.Add(t, longNow); } return t; } /// <summary> /// 将对象放入池中 /// </summary> /// <param name="t">对象实例</param> internal void ReturnObjectToPool(T t) { if (!object.Equals(null, t)) { lock (this) { // 设置对象为空闲对象 objLocked.Remove(t); objUnLocked.Add(t, DateTime.Now.Ticks); } } } } }
DBConn类:
using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; namespace objectPool { /// <summary> /// 数据库连接对象池 /// </summary> class DBConn : objectPool<SqlConnection> { /// <summary> /// 私有构造函数 /// </summary> private DBConn() { } /// <summary> /// 返回自身对象(Singleton) /// </summary> public static readonly DBConn Instance = new DBConn(); /// <summary> /// 默认连接语句 /// </summary> private static string strConnStr = @"Data Source=WORK0249\;Initial Catalog=AdventureWorks;Persist Security Info=True;User ID=sa;Password=sa"; /// <summary> /// 连接语句(属性) /// </summary> public string StrConnStr { get { return strConnStr; } set { strConnStr = value; } } /// <summary> /// 创建数据库连接对象 /// </summary> /// <returns>已打开的数据库连接对象</returns> protected override SqlConnection Create() { SqlConnection conn = new SqlConnection(strConnStr); conn.Open(); return conn; } /// <summary> /// 验证连接状态 /// </summary> /// <param name="t">数据库连接对象</param> /// <returns>连接状态Open : true Close:false</returns> protected override bool ValiDate(SqlConnection t) { try { return !(t.State.Equals(ConnectionState.Closed)); } catch (SqlException) { return false; } } /// <summary> /// 关闭数据库连接 /// </summary> /// <param name="t">数据库连接对象</param> protected override void Expire(SqlConnection t) { try { t.Close(); } catch (SqlException) { } } /// <summary> /// 从池中获取数据库连接 /// </summary> /// <returns>数据库连接对象</returns> public SqlConnection BorrowDBConn() { try { return base.GetObjectFromPool(); } catch (Exception ex) { throw ex; } } /// <summary> /// 将连接对象放入池中 /// </summary> /// <param name="conn">数据库连接对象</param> public void ReturnDBConn(SqlConnection conn) { base.ReturnObjectToPool(conn); } } }
使用示例:
using System; using System.Collections.Generic; using System.Text; using System.Data.SqlClient; namespace objectPool { class Program { static void Main(string[] args) { DBConn dbconn = DBConn.Instance; // 从池中取出对象 SqlConnection conn = dbconn.BorrowDBConn(); string strSql = "SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode, " + "rowguid, ModifiedDate FROM Person.Address"; SqlCommand command = new SqlCommand(strSql, conn); SqlDataReader reader = command.ExecuteReader(); while (reader.Read()) { Console.Write(reader[0]); } // 将对象放入池中 dbconn.ReturnDBConn(conn); Console.Read(); } } }
KidYang