在工作中,可能你的用戶並沒有那麼聽話,隨意的去點擊你的按鈕,如果你的按鈕時間這個時候是在訪問同一個sqlite 數據庫,那麼這個時候你可能會考慮多線程了,這裏把我自己遇到的多線程訪問數據庫中遇到的問題總結於此:
對於單個sqlite文件打開數據庫的時候要添加 synchronized 否則會提示:wait for second beause XXXis locked
這裏需要一個打開數據庫的方法:
<span style="font-size:14px;">public synchronized static SQLiteDatabase geSDCardSQLiteDatabase(){</span>
<span style="font-size:14px;">
<span style="white-space:pre"> </span> if (db==null) { //採用單例模式
Boolean tagBoolean =FileUtils.isExists(pathString);
db = SQLiteDatabase.openOrCreateDatabase(pathString , null);
if (!tagBoolean) {//如果不存在那麼需要創建表
db.execSQL(CreateTable.createTable());
}
}
return db;
} </span>
這裏講一下爲什麼要用單例模式:
如果不用單例模式,那麼 每次獲取數據庫連接的時候 都會調用 SQLiteDatabase.openOrCreateDatabase(pathString , null); 那麼這時候其實就是相當於打開一個已經打開的文件,這時候自然不會成功!這個裏的道理跟 synchronized 的用意應該是一樣的因爲當
SQLiteDatabase.openOrCreateDatabase(pathString , null);還沒有執行完成的時候又一個方法調用了,該方法 就會引起同時調用 打開自然引起錯誤。</span>
打開一個數據庫後 因爲是多線程所以 不同的方法在不同的時候會用完數據庫,這裏就牽扯到關閉數據庫了,這裏需要考慮一個方法如何保證別的方法還在用的時候不關閉數據庫,因爲我們用的是同一個連接,如果你關閉了,別人自然不能用,同理,你正在用的時候別人把這個連接關閉了,這個時候自然會出問題!這個時候一般報的就是
<span style="font-size:14px;">Database is closed!</span>
所以,這裏需要考慮用到鎖的概念了 ,保證如果有線程再用數據庫連接這個連接就不會被kill
於是:
每得到一次連接 我們都需要鎖定一次
public synchronized static void lockDb()
{
//沒有鎖定的時候纔可以更改狀態
if (!isLock) {
isLock=true;
lockCount=0;//說明第一次鎖定
}
lockCount++;
}
這樣就能得到當前有多少個線程在使用數據庫連接
那麼關閉的時候我們也需要調用解鎖:
//解鎖數據庫
public synchronized static void unLockDb()
{
lockCount--;//發現自己是最後一個那麼直接 解鎖
if (lockCount==0) {
isLock=false;
close();
}
}
</pre><pre name="code" class="java">public synchronized static void close()
{
//如果鎖着的 那麼直接 不關閉
if (!isLock) {
if (db!=null) {
db.close();
</span> db=null;
}
}
}
這樣在沒有線程使用連接兒的時候關閉即可!
這樣就確保了,如果多個線程調用數據庫那麼使用的一定是一個數據庫連接!那麼就實現了多線程訪問數據庫!
以上這些或許講的不夠透徹,但是一個宗旨就是 要用就一直使用一個數據庫連接 ! 這也算是個人的愚見吧!經測試,如果不用同步鎖,一直使用一個連接不關閉是也可以的! 站在自己理解程度上來看,如果你有不同見解歡迎指正分享!