3

私はこのC#コードを持っています:

public class Locking
{

    private int Value1; private int Value2;

    private object lockValue = new Object();
    public int GetInt1(int value1, int value2)
    {
        lock (lockValue)
        {
            Value1 = value1;
            Value2 = value2;
            return GetResult();
        }

    }

    public int GetInt2(int value1, int value2)
    {
        lock (lockValue)
        {
            return GetInt1(value1, value2);
        }
    }

    private int GetResult()
    {
        return Value1 + Value2;
    }


}

基本的に、実行するとデッドロックが発生することが予想さGetInt2れますが、コードは実行されます。どんな良い説明でも。

4

3 に答える 3

13

スレッドが既にオブジェクトのロックを保持していない限り、実行中のlockスレッドをブロックします。

この場合、実行中のスレッドは 1 つだけです。でロックを取得lockValueし、 にGetInt2進みます。GetInt1そこで再びロック ステートメントに遭遇しlockValueます。これはすでに保持されているため、続行が許可されます。

于 2013-06-18T10:07:58.063 に答える
7

C#のlockステートメントはシンタックス シュガーであり、コンパイラによって の呼び出しとして解釈されMonitor.Enterます。それは文書化されています(「モニター」セクションで)

lock (x)
{
    DoSomething();
}

と同等です

System.Object obj = (System.Object)x;
System.Threading.Monitor.Enter(obj);
try
{
    DoSomething();
}
finally
{
    System.Threading.Monitor.Exit(obj);
}

Monitor.Enter状態のドキュメント

Enterブロックせずに同じスレッドを複数回呼び出すことは正当です。ただし、オブジェクトを待機している他のスレッドがブロックを解除する前に、同じ数のExit呼び出しを呼び出す必要があります。

上記から明らかなように、関与するスレッドが 1 つだけである限り、特定のコードではデッドロックが発生しません。

于 2013-06-18T10:10:17.107 に答える