2013-04-30 64 views
5

在我主要活動的onCreate()方法中,我調用dbManager的構造函數,我調用open函數創建一個SQLiteOpenHelper的實例,然後我調用它的getWritableDatabase()。 在UIThread中,我將記錄添加到數據庫並將這些記錄保存到ArrayList。其他兩個線程檢查ArrayList做什麼,並更新列表和數據庫。 現在我想在UI中添加一個按鈕,使用AsyncTask來刪除數據庫和列表記錄。 我讀過SqliteOpenHelper對象存放在一個數據庫連接上。所以如果有一個助手實例只有一個數據庫連接。這個連接可以在多個線程中使用,並且SqliteDatabase對象使用java鎖來保持訪問序列化。所以如果我有多個線程在數據庫上寫入,一個線程會等到上一個線程完成他的操作?
添加新功能(全部刪除)可能會產生問題,因爲我必須避免這兩個線程中的一個嘗試編輯不再存在的記錄。我怎樣才能實現我的目標?謝謝。Android:在SQLite數據庫上寫入多個線程

+0

你應該實現消費者和生產者模式,它會幫你建立一個請求隊列,不要並行寫入數據庫。 – IamStalker 2013-04-30 14:11:15

+0

取決於你如何實現你的編輯,但一個SQL更新返回n,其中n是修改的項目的數量,如果沒有匹配where子句的記錄存在,它可以是0。 – njzk2 2013-04-30 14:22:36

+0

1)您不應該在UI線程上執行數據庫操作。 2)只有一個線程讀/寫ArrayList。 @IstStalker爲什麼不寫並行到DB? – m0skit0 2013-04-30 14:28:53

回答

4

的databese:

只要您只使用一個幫手,你是線程安全的,而無需做任何事情。
在多線程應用程序中,僅在創建助手時才需要​​。 如果要定義關鍵部分(多個原子操作),則可以使用transacion
包裹每個調用與getWritableDatabase()close(false)

public void doSomething() { 
    SQLiteDatabase tdb = getWritableDatabase(); 
    dbInstance.writeSomething(tdb, 1); 
    close(false); 
} 

這樣,我有多個線程讀取,並沒有任何問題寫入數據庫。

您的應用程序邏輯:

使用內存來跟蹤對象的狀態,並使用數據庫作爲唯一的存儲。所以如果一個線程從數據庫中刪除行 - 你可以立即在內存中更新你的對象,並相應地處理你的UI。
如果你的數據非常大,你可以保存在內存中只有髒行ID的SparseArray
這裏同步一些操作可能很有用。

+0

你的同步在你的代碼片段中用於何處? – IamStalker 2013-04-30 20:30:52

+0

數據庫幫助程序正在進行維護數據庫完整性所需的所有同步。與數據庫無關 - 在應用程序邏輯中,開發人員可能需要在代碼中的關鍵部分進行同步以保持業務邏輯的完整性。 – auval 2013-04-30 23:26:54

+0

沒有這樣的限制,一百個線程可以一起讀取和寫入同一個數據塊,沒有任何問題。使用一個幫手。這是*不*當編寫多線程應用程序時問題所在。 – auval 2013-05-01 07:52:27

0

所以如果我有多個線程寫在數據庫上,一個線程將 等到上一個完成他的操作?

不需要如此。有關更多詳細信息,請參閱this。無論如何,這取決於數據庫引擎,應該是透明的。

添加新的功能(刪除所有)可能會造成問題, 因爲我必須避免兩個線程之一可以嘗試編輯 記錄不再存在。我怎樣才能實現我的目標?

只有一個線程更新數據庫。其他線程只修改ArrayList - 也應注意,因爲ArrayList不是線程安全的,請考慮使用Collections#synchronizedList()

相關問題