1

ここでjdk 5 ReentrantLockの機能を(ある程度)理解しています

しかし、なぜ「再入可能」ロックが必要なのでしょうか? つまり、スレッドがすでにオブジェクトのロックを取得している場合、なぜそれを再度取得する必要があるのでしょうか?

4

2 に答える 2

3

次の理論的な例を考えてみましょう。GUI のリスト ボックス内のいくつかの項目を更新しているときに、バックエンド データを保護するためにロックを使用しています。アイテムをループして変更します。そうしている間、リスト ボックスは、ハンドラーが登録されているイベント (おそらく、Selection Changed イベントなど) を発生させます。このハンドラーは、新しいアイテムを処理するために同じロックもロックします。ロックが再帰的でない場合、このスレッドはロックを取得しようとする 2 回目の試行でデッドロックします。

于 2013-08-14T17:02:54.610 に答える
2

再入可能ロックは、リソースがすべての形式の任意のタイミングのアクセスを許容できないが、ネストされた実行コンテキストで発生する可能性のある特定のアクセス パターンを許容できる場合に役立ちます。多くの場合、それらの使用法は見栄えが悪くずさんですが、再入可能ロックが不要になるように配置するよりも、再入可能ロックの動作が保証されるように配置する方が簡単な場合があります。

多くの言語はデフォルトでロックを再入可能にしていますが、それは必ずしも良いことではないことに注意してください。コードがロックを取得し、そのスレッド内の他のコードが同じロックのトークンを取得しようとした場合、ロックが解放されるまで 2 番目の要求を待機させることは、あまり生産的ではないことは明らかです。ただし、これは、2 番目の要求がロックへのアクセスを許可する必要があることを意味するものではありません。多くの場合、適切なアクションは、2 番目のリクエストが即座に例外をスローすることです (ロックが解放されるまでアクセスは許可されるべきではなく、リクエストが許可されるまで発生することはありません (発生するべきではありません)。 ) またはコードは別の方法で終了します (例外は最も自然な選択です)。このような状況は、データ構造が一貫性のない状態にあるときに、ロックで保護されたデータ構造を変更していたメソッドが、データ構造を使用することが予期されていない外部コードを呼び出した場合に適用されます。コードが予期せずデータ構造を使用しようとした場合、決して取得できないロックを永久に待機するか、無愛想にロックに進んで無効なデータにアクセスするよりも、すぐに例外で失敗するようにする方がよい場合があります。

保護されたリソースがその不変条件のすべてではなく一部を満たしているときにコードがネストされたルーチンを呼び出す場合や、ネストされたルーチンが何らかの変更を加えることを外側のコードが期待する場合があります。このような場合、再入可能ロックが適切かもしれませんが、コードが実行すべきでないことを実行しないように注意する必要があります。再入可能ロックの利点の 1 つは、ロックが保持された状態でネストされた呼び出しを行うコードがその約束/要件を示すフラグを設定し、ロックを取得するコードがエントリ時にそれらのフラグをテストする場合、フラグが予測可能な状態でのみ操作されることを保証できることです。シーケンス。2 つの異なるスレッドがリソースを同時に使用しようとしている場合、このようなことは不可能です。

于 2013-08-14T17:35:59.583 に答える