1

リソースのリストがあります。読み取りプロセスはこれらのそれぞれに同時にアクセスできますが、書き込みプロセスが来て、更新中にリソースで読み取りプロセスが実行されていない必要があるオブジェクトを変更することがあります。JavaReentrantReadWriteLockはこの状況を正しく処理しているように見えるので、アプリケーションのスループットを最大化するために、これらの 1 つを各リソースに割り当てました。ただし、エントリの削除に問題があります。一部の書き込みプロセスは、アクセス可能なリソースをこのリストから削除する場合があります。

次のシナリオを想像してください。

  • 削除プロセスは、削除されるリソースのロックを取得します
  • 一方、リーダープロセスはreadLock().lock()ステートメントに到達し、書き込みロックが解放されるのをキューで待機し始めます
  • 削除プロセスは、リストからリソースを削除し、リソースでシャットダウンを呼び出して終了します
  • 削除プロセスは、リソースの書き込みロックを解放します
  • 最初の待機中の読み取りプロセスが再開され、現在矛盾しているリソース オブジェクトの処理が開始されます。

この状況を正しく処理するにはどうすればよいですか? 待機中の読み取りスレッドで呼び出すことができればよいのですが、リストの作成中に新しいスレッドが読み取りロックを取得できるためinterrupt()、API の説明にgetQueuedReaderThreads信頼性がないと記載されているため、すべてのスレッドをキャンセルするかどうか確信が持てません。 .

4

1 に答える 1

3

「削除済み」フラグを各リソースに関連付ける方がはるかに簡単だと思います。

リーダーがロックを取得すると、そのフラグを確認し、リソースが削除されたときの状況を正しく処理する必要があります。ライターはリソースを削除した直後にロックを解放し、各リーダーはリソースが削除されたことを発見した直後にロックを解放する必要があるため、ここで長いブロックが発生することはないため、スレッドを中断する必要はありません。

この動作を独自の API の背後に隠すことができます (たとえば、ResourceDeletedExceptionリーダーが削除されたリソースのロックを取得したときのようなものをスローできます)。

于 2012-10-11T09:19:30.947 に答える