aとbの2 つのオブジェクトがあるとします。
両方のオブジェクトを SyncLock したい。
これは実現可能ですか?ネストされた SyncLock ステートメントで実行できますか? そのような操作の危険性は何ですか?
編集
おそらく、デッドロックを回避するためにリファクタリングするにはどうすればよいでしょうか?
ネストされたロックは機能しますが、危険の 1 つは、オブジェクトを常に同じ順序でロックする必要があることです。そうしないと、デッドロックが発生する可能性があります。
編集:ロックの正しい順序を強制しようとすることに関する2番目の質問に答えるには:
これを回避するための可能な解決策は、ロックを次のような一般的なロック メソッドにカプセル化することです。
public void LockAndDoWork(Action action)
{
lock(lockObject1)
{
lock(lockObject2)
{
action();
}
}
}
これは、次のように使用できます。
Thread1: LockAndDoWork(() => {do some work....});
Thread2: LockAndDoWork(() => {do some other work...});
これにより、この潜在的な問題を回避できます。クライアント コードからこれらのオブジェクトへの可視性を制限できる場合は特に便利です。
おそらく私は尋ねるべきです、デッドロックを回避するためにどのようにリファクタリングできますか?
すべての同期ロックを優先度の高い順序で定義し、常に最も高い優先度を最初に取得します。
これは難しいことです。優先度の低いロックを保持している1つのコードブロックが、優先度の高いロックを取得する必要があるヘルパーコードを呼び出す可能性がある場合、大幅なリファクタリングが必要になります。
それは可能ですが、このコードを実行している 2 つのスレッドが同時に両方のロックを取得しようとするとどうなるかを考慮する必要があります。たとえば、スレッド 1 がオブジェクト 1 をロックし、スレッド 2 がオブジェクト 2 をロックしている場合などです。キューデッドロック。
私よりも優れた誰かが、安全なサンプルコードを提供できます:)