メイン アクティビティのonCreate()
メソッドで、dbManager のコンストラクターを呼び出します。a のインスタンスを作成する open 関数をSQLiteOpenHelper
呼び出し、その上で を呼び出しますgetWritableDatabase()
。UIThread 内でデータベースにレコードを追加し、それらのレコードを ArrayList に保存します。他の 2 つのスレッドは、ArrayList の処理をチェックしてから、リストとデータベースを更新します。ここで、UI にボタンを追加して、AsyncTask
. 私はそれを読んだSqliteOpenHelper
オブジェクトは 1 つのデータベース接続で保持されます。したがって、ヘルパー インスタンスが 1 つある場合、データベース接続は 1 つだけです。この接続は複数のスレッドから使用でき、SqliteDatabase オブジェクトは Java ロックを使用してアクセスをシリアル化します。複数のスレッドがデータベースに書き込みを行っている場合、スレッドは前のスレッドが操作を完了するまで待機しますか?
新しい機能を追加する (すべて削除する) と、問題が発生する可能性があります。これは、2 つのスレッドのいずれかが存在しないレコードを編集しようとするのを回避する必要があるためです。どうすれば目標を達成できますか? ありがとう。
2 に答える
データベース:
ヘルパーを 1 つだけ使用する限り、何もする必要なくスレッド セーフになります。マルチスレッド アプリでは、ヘルパーの作成のみ
が必要です。クリティカル セクション (複数のアトミック オペレーション) を定義する場合は、 transacionsynchronized
を使用できます。各呼び出しをand
でラップします。getWritableDatabase()
close(false)
public void doSomething() {
SQLiteDatabase tdb = getWritableDatabase();
dbInstance.writeSomething(tdb, 1);
close(false);
}
このようにして、複数のスレッドでデータベースの読み取りと書き込みを問題なく行うことができます。
アプリのロジック:
メモリを使用してオブジェクトの状態を追跡し、データベースをストレージとしてのみ使用します。したがって、1 つのスレッドがデータベースから行を削除した場合、すぐにメモリ内のオブジェクトを更新し、それに応じて UI を処理できます。
データが非常に大きい場合、SparseArray
ダーティ行 ID のみをメモリに保持できます。
ここで一部の操作を同期すると便利な場合があります。
複数のスレッドがデータベースに書き込みを行っている場合、スレッドは前のスレッドが操作を完了するまで待機しますか?
そうである必要はありません。詳しくはこちらをご覧ください。とにかく、これは DB エンジン次第であり、透過的であるべきです。
新しい機能を追加する (すべて削除する) と、問題が発生する可能性があります。これは、2 つのスレッドのいずれかが存在しないレコードを編集しようとするのを回避する必要があるためです。どうすれば目標を達成できますか?
DB を更新するスレッドは 1 つだけにします。他のスレッドはArrayList
-also を変更するだけで、ArrayList
スレッドセーフではないので注意してください。使用を検討してCollections#synchronizedList()
ください。