5

メイン アクティビティのonCreate()メソッドで、dbManager のコンストラクターを呼び出します。a のインスタンスを作成する open 関数をSQLiteOpenHelper呼び出し、その上で を呼び出しますgetWritableDatabase()。UIThread 内でデータベースにレコードを追加し、それらのレコードを ArrayList に保存します。他の 2 つのスレッドは、ArrayList の処理を​​チェックしてから、リストとデータベースを更新します。ここで、UI にボタンを追加して、AsyncTask. 私はそれを読んだSqliteOpenHelperオブジェクトは 1 つのデータベース接続で保持されます。したがって、ヘルパー インスタンスが 1 つある場合、データベース接続は 1 つだけです。この接続は複数のスレッドから使​​用でき、SqliteDatabase オブジェクトは Java ロックを使用してアクセスをシリアル化します。複数のスレッドがデータベースに書き込みを行っている場合、スレッドは前のスレッドが操作を完了するまで待機しますか?
新しい機能を追加する (すべて削除する) と、問題が発生する可能性があります。これは、2 つのスレッドのいずれかが存在しないレコードを編集しようとするのを回避する必要があるためです。どうすれば目標を達成できますか? ありがとう。

4

2 に答える 2

4

データベース:

ヘルパーを 1 つだけ使用する限り、何もする必要なくスレッド セーフになります。マルチスレッド アプリでは、ヘルパーの作成のみ
が必要です。クリティカル セクション (複数のアトミック オペレーション) を定義する場合は、 transacionsynchronizedを使用できます。各呼び出しをand でラップします。
getWritableDatabase()close(false)

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

このようにして、複数のスレッドでデータベースの読み取りと書き込みを問題なく行うことができます。

アプリのロジック:

メモリを使用してオブジェクトの状態を追跡し、データベースをストレージとしてのみ使用します。したがって、1 つのスレッドがデータベースから行を削除した場合、すぐにメモリ内のオブジェクトを更新し、それに応じて UI を処理できます。
データが非常に大きい場合、SparseArrayダーティ行 ID のみをメモリに保持できます。
ここで一部の操作を同期すると便利な場合があります。

于 2013-04-30T14:29:00.703 に答える
0

複数のスレッドがデータベースに書き込みを行っている場合、スレッドは前のスレッドが操作を完了するまで待機しますか?

そうである必要はありません。詳しくはこちらをご覧ください。とにかく、これは DB エンジン次第であり、透過的であるべきです。

新しい機能を追加する (すべて削除する) と、問題が発生する可能性があります。これは、2 つのスレッドのいずれかが存在しないレコードを編集しようとするのを回避する必要があるためです。どうすれば目標を達成できますか?

DB を更新するスレッドは 1 つだけにします。他のスレッドはArrayList-also を変更するだけで、ArrayListスレッドセーフではないので注意してください。使用を検討してCollections#synchronizedList()ください。

于 2013-04-30T14:37:10.993 に答える