近期在一個數據推送服務器中,為了方便起見使用Sqlite作為數據庫引擎,以方便部署。在初始版本中,為了方便全局訪問,定義了一個DBHelper類作為數據庫訪問類,使用單實例,並使用一個靜態方法GetInstance()。后面經過仔細思考,發現,這樣可能會存在並發訪問沖突,因此加入連接池機制來防止沖突。
原理是這樣:定義一個靜態的DBHelper的棧對象,並且在初始化的時候創建N個連接。每次需要使用數據連接的時候調用GetInstance(),該函數先檢測棧是否非空,是則彈出一個DBHelper對象,否則,創建一個新的DBHelper對象。在數據訪問完成后,再調用ReleaseInstance將DBHelper對象壓入棧中。
下面給出代碼,去除了DBHelper的業務邏輯部分。
class DBHelper { private static Stack<DBHelper> mInstancePool = new Stack<DBHelper>(); private static object mLockIntancePool=new object(); public static DBHelper GetInstance() { DBHelper dbHelper = null; lock (mLockIntancePool) { if (mInstancePool.Count != 0) { dbHelper = mInstancePool.Pop(); } else { dbHelper = new DBHelper(); } } return dbHelper; } public static void ReleaseInstance(DBHelper dbHelper) { lock (mLockIntancePool) { mInstancePool.Push(dbHelper); } } static DBHelper() { for (int i = 0; i < 10; i++) { mInstancePool.Push(new DBHelper()); } } private DBHelper() { mConnection = SQLiteClass.CreateConnectionFromFile(@"data.db"); }
}