いくつかのテーブルを持つデータベースがあります。複数のスレッドを使用してテーブルを更新したい。すべてのスレッドでSQLiteDatabaseの同じインスタンスを使用します。
このアプローチが正しいかどうかを提案してください。 Sqliteデータベースはスレッドセーフですか? 2つの異なるスレッドが、異なる値のセットの同じテーブルを同時に更新できますか。
[間違い:]いいえ、デフォルトではスレッドセーフではありません。ロック関連のSQLiteHelperメソッドを使用して、スレッドセーフを提供する必要があります。
[EDIT]:SQLiteDatabaseクラスは、デフォルトでロックメカニズムを提供します(参照コメント)、マルチスレッドで実行している場合は、スレッドセーフにするために何かを変更することを検討する必要はありません。
このドキュメントで「スレッド」を検索: http://developer.Android.com/reference/Android/database/sqlite/SQLiteDatabase.html
そして続きを読む:
AndroidはJavaロックメカニズムを使用して、SQLiteデータベースアクセスのシリアル化を維持します。したがって、複数のスレッドが1つのdbインスタンスを持っている場合、常にシリアル化された方法でデータベースを呼び出しますそしてもちろんデータベースはスレッドセーフです。
シングルスレッドからデータベースを使用していることを確認した場合、setLockingEnable(false)
を呼び出すことによってデータベースの内部ロックを無効に設定するオプションがありましたが、このメソッドはAPIレベル16から 非推奨 を取得し、使用されなくなりました。このメソッドの実装がSQLiteDatabase
クラスにある場合、そこには何も記述されていません。つまり、空のメソッドです。
_public void setLockingEnabled (boolean lockingEnabled)
_
このメソッドは何もしません。使用しないでください。
注意が必要なことの1つは、ヘルパークラスのインスタンスを1つ(つまり、シングルトンにする)作成し、同じインスタンスを複数のスレッドで共有し、操作の合間にデータベースでclose()
を呼び出さないことです。そうしないと、次の例外が発生する可能性があります。
_Java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase
_
そのため、データベースへのアクセスの間にdatabase.close()
を呼び出さないでください。すべての操作が完了すると、データベースは内部的に閉じる操作を実行します。
setLockingEnabled を使用すると、データベースがスレッドセーフかどうかを制御できます。
クリティカルセクションを囲むロックを使用して、SQLiteDatabaseをスレッドセーフにするかどうかを制御します。これは非常にコストがかかるため、DBが単一のスレッドでのみ使用されることがわかっている場合は、これをfalseに設定する必要があります。デフォルトはtrueです
だから私はこれがあなたの質問に答えると思います。
メソッドsetLockingEnabledはAPIレベル16で廃止されました