亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android SQLite3多線程操作問題研究總結

2020-04-11 11:38:46
字體:
來源:轉載
供稿:網友

最近做項目時在多線程讀寫數據庫時拋出了異常,這自然是我對SQlite3有理解不到位的地方,所以事后仔細探究了一番。

1.關于getWriteableDataBase()和getReadableDatabase()的真正作用
getWriteableDataBase()其實是相當于getReadableDatabase()的一個子方法,getWriteableDataBase()是只能返回一個以讀寫方式打開的SQLiteDatabase的引用,如果此時數據庫不可寫時就會拋出異常,比如數據庫的磁盤空間滿了的情況。而getReadableDatabase()一般默認是調用getWriteableDataBase()方法,如果數據庫不可寫時就會返回一個以只讀方式打開的SQLiteDatabase的引用,這就是二者最明顯的區別。

關鍵源碼如下:

public synchronized SQLiteDatabase getWritableDatabase() {  if (mDatabase != null) {    if (!mDatabase.isOpen()) {    // darn! the user closed the database by calling mDatabase.close()    mDatabase = null;    } else if (!mDatabase.isReadOnly()) {    return mDatabase; // The database is already open for business    }  }... ...public synchronized SQLiteDatabase getReadableDatabase() {  if (mDatabase != null) {    if (!mDatabase.isOpen()) {    // darn! the user closed the database by calling mDatabase.close()    mDatabase = null;    } else {    return mDatabase; // The database is already open for business    }  } ... ...  try {    return getWritableDatabase();  }... ...

2.SQLiteDatabase的同步鎖

其實在只使用一個SQLiteDatabase的引用時,SQLiteDatabase對CRUD操作都會加上一個鎖(因為是db文件,所以精確至數據庫級),這就保證了在同一時間你只能進行一項操作,無論是不是在同一個線程中,這就導致了如果你在程序中對SQLiteOpenHelper使用了單例模式,那么你對數據庫讀寫進行任何的優化操作都是"徒勞"。

3.多線程讀數據庫

仔細看源碼你會發現,在數據庫操作中只有add,delete,update會調用lock(),而query()是不會調用的,但是在加載數據時,調用了SQLiteQuery的fillWindow方法,而該方法依然會調用SQLiteDatabase.lock(),所以要想真正的實現多線程讀數據庫,只能每個線程使用各自的SQLiteOpenHelper對象進行讀操作,這樣就可避開同步鎖。關鍵源碼如下:

/* package */ int fillWindow(CursorWindow window,  int maxRead, int lastPos) {  long timeStart = SystemClock.uptimeMillis();  mDatabase.lock();  mDatabase.logTimeStat(mSql, timeStart, SQLiteDatabase.GET_LOCK_LOG_PREFIX);  try {... ...

4.多線程讀寫

實現多線程讀寫的關鍵是enableWriteAheadLogging屬性,這個方法 API Level 11添加的,也就是所3.0以上的版本就基本不可能實現真正的多線程讀寫了。簡單的說通過調用enableWriteAheadLogging()和disableWriteAheadLogging()可以控制該數據是否被運行多線程讀寫,如果允許,它將允許一個寫線程與多個讀線程同時在一個SQLiteDatabase上起作用。實現原理是寫操作其實是在一個單獨的log文件,讀操作讀的是原數據文件,是寫操作開始之前的內容,從而互不影響。當寫操作結束后讀操作將察覺到新數據庫的狀態。當然這樣做的弊端是將消耗更多的內存空間。

5.多線程寫

這個就不用多想了,SQLite壓根不支持,如果實在有需求可以使用多個數據庫文件。

6.備注

(1)你有沒有想SQLite最多支持多少個數據庫連接,其實在官方API文檔(enableWriteAheadLogging ()方法)中給出了最精確的答案:The maximum number of connections used to execute queries in parallel is dependent upon the device memory and possibly other properties.就是看你有多少內存,但是我感覺這話說的有點大,是不?哈哈。

(2)當你在多線程中只使用一個SQLiteDatabase的引用時,需要格外注意你SQLiteDataBase.close()調用的時機,因為你是使用的同一個引用,比如在一個線程中當一個Add操作結束后立刻關閉了數據庫連接,而另一個現場中正準備執行查詢操作,但此時db已經被關閉了,然后就會報異常錯誤。此時一般有三種解決方案,①簡單粗暴給所有的CRUD添加一個 synchronized關鍵字;②永遠不關閉數據庫連接,只在最后退出是關閉連接。其實每次執行getWriteableDataBase()或getReadableDatabase()方法時,如果有已經建立的數據庫連接則直接返回(例外:如果舊的連接是以只讀方式打開的,則會在新建連接成功的前提下,關閉舊連接),所以程序中將始終保持有且只有一個數據庫連接(前提是單例),資源消耗的很少。③可以自己進行引用計數,簡單示例代碼如下:

//打開數據庫方法public synchronized SQLiteDatabase openDatabase() {if (mOpenCounter.incrementAndGet() == 1) { // Opening new database try { mDatabase = sInstance.getWritableDatabase(); } catch (Exception e) { mDatabase = sInstance.getReadableDatabase(); } }return mDatabase;}//關閉數據庫方法public synchronized void closeDatabase() { if (mOpenCounter.decrementAndGet() == 0) { // Closing database mDatabase.close(); } }

 (3)還有一些比較好的習慣和常識,例如關閉Cursor,使用Transaction,SQLite存儲數據時其實不區分類型,以及SQLite支持大部分標準SQL語句,增刪改查語句都是通用的等等。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品国模在线| 亚洲999一在线观看www| 日韩中文字幕免费看| 国产精品福利片| 大桥未久av一区二区三区| 高清一区二区三区四区五区| 97超级碰在线看视频免费在线看| 日韩一二三在线视频播| 日韩欧美中文免费| 亚洲电影成人av99爱色| 亚洲国产精品yw在线观看| 亚洲午夜激情免费视频| 亚洲а∨天堂久久精品9966| 亚州国产精品久久久| 亚洲成人激情图| 中文字幕欧美国内| 欧美丝袜第一区| 亚洲精品在线视频| 国产欧美日韩精品在线观看| 色偷偷偷亚洲综合网另类| 夜夜嗨av色综合久久久综合网| 热99久久精品| 国产精品电影网站| 97国产精品视频人人做人人爱| 亚洲欧洲激情在线| 欧美特黄级在线| 亚洲欧美日韩精品久久亚洲区| 中文字幕日韩精品在线| 国产精品成人av在线| 亚洲娇小xxxx欧美娇小| 欧美国产一区二区三区| 欧美丰满少妇xxxxx做受| 91av在线看| 久久久中文字幕| 欧美最顶级丰满的aⅴ艳星| 亚洲最新av在线| 欧美日韩亚洲一区二区三区| 国产午夜精品美女视频明星a级| 国产乱肥老妇国产一区二| 国产欧美 在线欧美| 欧美日韩ab片| 国产精品夫妻激情| 欧美大片大片在线播放| 欧美精品在线极品| 成人深夜直播免费观看| 欧美一级大胆视频| 欧美激情日韩图片| 欧美黑人极品猛少妇色xxxxx| 亚洲精品永久免费| 国产免费一区视频观看免费| 欧美性xxxx极品高清hd直播| 国内精品在线一区| 亚洲国产天堂网精品网站| 91牛牛免费视频| 日韩视频中文字幕| 亚洲片国产一区一级在线观看| 亚洲国产精品一区二区久| 国产精品电影久久久久电影网| 亚洲男女自偷自拍图片另类| 日韩av影片在线观看| 91老司机在线| 久久久久国产一区二区三区| 国产日韩欧美在线| 亚洲精品视频网上网址在线观看| 精品国产乱码久久久久久婷婷| 97视频免费看| 一区二区三区精品99久久| 欧美日韩精品国产| 亚洲免费伊人电影在线观看av| 欧美日韩午夜剧场| 日韩午夜在线视频| 色综合色综合网色综合| 亚洲综合中文字幕在线观看| 亚洲成人网在线观看| 久久精品国产免费观看| 国产一区二区三区在线看| 亚洲国产精品久久久久秋霞不卡| 日本午夜在线亚洲.国产| 国产免费一区二区三区香蕉精| 亚洲精品美女久久久| 亚洲美女精品久久| 欧美xxxx做受欧美| 丝袜美腿亚洲一区二区| 久热精品视频在线观看| 欧美另类在线观看| 精品久久中文字幕| 亚洲午夜精品视频| 国产精品夫妻激情| 国产亚洲精品日韩| 国产精品高潮视频| 欧美激情乱人伦| 亚洲精品国产精品乱码不99按摩| 国产在线拍揄自揄视频不卡99| 日韩精品高清在线| 国产欧美亚洲精品| 九九热视频这里只有精品| 欧美国产日韩视频| 日韩亚洲一区二区| 亚洲国产美女久久久久| 黄网动漫久久久| 日韩福利在线播放| 亚洲一区二区三区久久| 日韩在线一区二区三区免费视频| 久久久欧美一区二区| 亚洲日本欧美日韩高观看| 日韩美女视频免费在线观看| 精品亚洲男同gayvideo网站| 97在线观看免费| 欧美野外wwwxxx| 日韩精品亚洲精品| 国产精品久久久久久久久久新婚| 日韩成人高清在线| 91po在线观看91精品国产性色| 欧美日韩国产中文精品字幕自在自线| www.久久色.com| 黄色一区二区三区| 538国产精品一区二区免费视频| 97激碰免费视频| 亚洲自拍偷拍区| 成人黄色网免费| 色偷偷91综合久久噜噜| 国产美女精彩久久| 亚洲一区二区久久久久久久| 亚洲欧美国产另类| 久久精品国产v日韩v亚洲| 欧美在线性视频| 国产最新精品视频| 亚洲欧美国产精品va在线观看| 成人在线观看视频网站| 久久久久久久久电影| 国产综合色香蕉精品| 全球成人中文在线| 欧美理论电影在线观看| 久久久国产在线视频| 国产精品免费久久久| 亚洲国产精品系列| 日本在线观看天堂男亚洲| 国产性猛交xxxx免费看久久| 中文字幕日韩电影| 日韩一二三在线视频播| 欧美一区二区三区……| 国模gogo一区二区大胆私拍| 亚洲午夜国产成人av电影男同| 91麻豆国产语对白在线观看| 高潮白浆女日韩av免费看| 北条麻妃一区二区在线观看| 国产综合久久久久| 国产一区二区三区在线看| 亚洲女人初尝黑人巨大| 国产香蕉精品视频一区二区三区| 亚洲成av人影院在线观看| 日韩精品视频免费在线观看| 国产日韩精品视频| 午夜精品久久久久久99热软件| 国产人妖伪娘一区91| 久久亚洲国产精品成人av秋霞| 久久国产精品影片| 亚洲第一中文字幕| 久久久欧美一区二区| 亚洲欧美日韩精品久久奇米色影视| 国产精品999999| 亚洲视频欧美视频| 久久久亚洲影院你懂的| 久久男人资源视频|