1. ホーム
  2. c#

[解決済み] lockステートメントは、ボンネットの中で何をするのでしょうか?

2022-03-16 14:48:58

質問

スレッドセーフでないオブジェクトを使用する場合は、このようにコードをロックで包むのですね。

private static readonly Object obj = new Object();

lock (obj)
{
    // thread unsafe code
}

では、複数のスレッドが同じコードにアクセスした場合(ASP.NETのWebアプリケーションで動作しているとします)、どうなるのでしょうか。それらはキューに入れられるのでしょうか?もしそうなら、どれくらいの時間待つのでしょうか?

ロックを使用することによるパフォーマンスへの影響はどの程度ですか?

解決方法は?

その lock 文は、C# 3.0では次のように変換されます。

var temp = obj;

Monitor.Enter(temp);

try
{
    // body
}
finally
{
    Monitor.Exit(temp);
}

C#4.0では が変更されました。 となり、以下のように生成されるようになりました。

bool lockWasTaken = false;
var temp = obj;
try
{
    Monitor.Enter(temp, ref lockWasTaken);
    // body
}
finally
{
    if (lockWasTaken)
    {
        Monitor.Exit(temp); 
    }
}

について、より詳しい情報を得ることができます。 Monitor.Enter が行います。 こちら . MSDNを引用します。

<ブロッククオート

使用方法 Enter のモニタを取得する。 パラメータとして渡されたオブジェクト。もし 他のスレッドが Enter をまだ実行していない場合、そのオブジェクトに対して 対応する Exit の場合、現在の がブロックされます。 はオブジェクトを解放する。これは 同じスレッドが Enter を使用せずに複数回 ブロックされますが、同じ数の Exit を呼び出す必要があります。 オブジェクトで待機している他のスレッド はブロックを解除する。

Monitor.Enter メソッドは無限に待ちます。 ない がタイムアウトになります。