次のコードは、.NET で C# を使用するとデッドロックが発生しますか?
class MyClass
{
private object lockObj = new object();
public void Foo()
{
lock(lockObj)
{
Bar();
}
}
public void Bar()
{
lock(lockObj)
{
// Do something
}
}
}
ベストアンサー1
いいえ、同じオブジェクトをロックしている限りはそうではありません。再帰コードは事実上すでにロックされているそして妨げられることなく継続することができます。
lock(object) {...}
は、モニタークラス。マークは指摘する、Monitor
許可する再入性、オブジェクトをロックしようとする試みが繰り返される現在のスレッドがすでにロックしているもの問題なく動作します。
ロックオンし始めると違うオブジェクトの場合は注意が必要です。特に以下の点に注意してください。
- 常に同じシーケンス内の指定された数のオブジェクトに対するロックを取得します。
- 常にロックを解除してください逆行する取得方法の順序。
これらのルールのいずれかを破ると、デッドロックの問題が発生する可能性が高くなります。ある時点で。
.NET でのスレッド同期について説明している優れた Web ページが 1 つあります。http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
また、一度にロックオンするオブジェクトはできるだけ少なくしてください。粗粒度ロック可能な場合はそうします。つまり、オブジェクト グラフが存在し、そのオブジェクト グラフのルートでロックを取得できるようなコードを記述できる場合は、そうします。つまり、そのルート オブジェクトに 1 つのロックがあるため、ロックを取得/解放する順序についてあまり心配する必要はありません。
(さらに注意すべき点として、あなたの例は技術的には再帰的ではありません。再帰的にするには、Bar()
通常は反復処理の一部として、それ自身を呼び出す必要があります。)