5

ClearがBuildがすでにロックしているのと同じオブジェクトをロックしようとすると、次のコードがデッドロックすることが予想されます。

void Main()
{
    (new SiteMap()).Build();
}

class SiteMap
{
    private readonly object _lock = new object();

    public void Build()
    {
        lock (_lock)
        {
            Clear();

            Console.WriteLine("Build");
        }
    }

    public void Clear()
    {
        lock (_lock)
        {
            Console.WriteLine("Clear");
        }
    }
}

出力:

クリア

建てる

編集1

回答ありがとうございます。

Clearのロック内にBuildの呼び出しを追加した場合(残りのコードは同じまま):

public void Clear()
{
    lock (_lock)
    {
        Build();

        Console.WriteLine("Clear");
    }
}

デッドロックが発生します(または、少なくともそれがLINQ Padのクラッシュだと思います)。

あなたの答えによると、それはまだ同じスレッドなので、これは起こらないはずです。

ありがとう!

4

3 に答える 3

8

C#では、ロックを保持しているスレッドは、ブロックせずに同じロックに入ることができます。

lockステートメントと、それが構築されているMonitorクラスは、.NETで再入可能です。


編集に応じて編集します。

呼び出しをinsideclearに追加してもBuild、コードはデッドロックしません。再帰的に呼び出します。それはブロックしていませんが、永久に実行されています(最終的に、StackOverflowExceptionが発生するまでBuildClearBuildClear

于 2012-05-17T17:55:11.303 に答える
5

のドキュメントは次のようにlock述べています。

別のスレッドがロックされたコードを入力しようとすると、オブジェクトが解放されるまで待機(ブロック)します。

キーワードは「another」です。スレッドはそれ自体をブロックするのではなく、他のスレッドだけをブロックします。別のスレッドがロックを所有していた場合、lockブロックされます。

これは多くの頭痛の種を節約します。

于 2012-05-17T17:58:13.417 に答える
4

すでにロックを適用した同じスレッド内でclearが呼び出されるため、私はしません。

于 2012-05-17T17:54:58.090 に答える