Lock クラス

定義

異なるスレッド間のコード領域で相互除外を実現するためのメカニズムを提供します。

public ref class Lock sealed
public sealed class Lock
type Lock = class
Public NotInheritable Class Lock
継承
Lock

注釈

Lock クラスを使用すると、リソースへの同時アクセスを防ぐために、プロセスのスレッド間で相互に排他的なアクセスを必要とするコードの領域 (一般的にクリティカル セクションと呼ばれます) を定義できます。 Lockを入力および終了できます。ここで、入り口と終了の間のコード領域は、ロックに関連付けられている重要なセクションです。 ロックに入ったスレッドは、ロックを終了するまでロックを保持または所有していると言われます。 最大 1 つのスレッドは、任意の時点でロックを保持できます。 スレッドは複数のロックを保持できます。 スレッドは、再帰的にロックを終了する前に複数回入力できます。 ロックをすぐに入力できないスレッドは、ロックを入力できるまで、または指定されたタイムアウトの有効期限が切れるまで待機できます。

EnterメソッドまたはTryEnterメソッドを使用してロックを入力する場合:

  • try/finally ブロックを使用して C# などの例外が発生した場合でも、スレッドが Exit でロックを終了していることを確認します。
  • C# async メソッドでロックを開始および終了する場合は、enter と exit の間に await がないことを確認します。 ロックはスレッドによって保持され、 await に続くコードは別のスレッドで実行される可能性があります。

C# using キーワードなどの返されたLock.Scopeを自動的に破棄する言語コンストラクトで EnterScope メソッドを使用するか、C# lock キーワードを使用することをお勧めします。これらは例外の場合にロックが終了するようにするためです。 これらのパターンには、 Enter/TryEnterExitを使用するよりもパフォーマンス上の利点がある場合もあります。 次のコード フラグメントは、ロックを開始および終了するためのさまざまなパターンを示しています。

public sealed class ExampleDataStructure
{
    private readonly Lock _lockObj = new();

    public void Modify()
    {
        lock (_lockObj)
        {
            // Critical section associated with _lockObj
        }

        using (_lockObj.EnterScope())
        {
            // Critical section associated with _lockObj
        }

        _lockObj.Enter();
        try
        {
            // Critical section associated with _lockObj
        }
        finally { _lockObj.Exit(); }

        if (_lockObj.TryEnter())
        {
            try
            {
                // Critical section associated with _lockObj
            }
            finally { _lockObj.Exit(); }
        }
    }
}

C# lock キーワードを使用する場合、またはロックの開始と終了と同様の場合、式の型は正確に System.Threading.Lockする必要があります。 式の型が ObjectTなどのジェネリック型など、他の何かである場合は、代わりに交換できない別の実装を使用できます ( Monitorなど)。 詳細については、関連する コンパイラ の仕様を参照してください。

Interrupt は、ロックの開始を待機しているスレッドを中断できます。 Windows STA スレッドでは、ロックを待機すると、待機中に同じスレッドで他のコードを実行できるメッセージ ポンプが許可されます。 待機の一部の機能は、カスタム SynchronizationContextによってオーバーライドできます。

ロックに入ったスレッド (再帰的なロックなど) は、ロックを完全に終了し、他のスレッドがロックに入ることができるように、同じ回数だけロックを終了する必要があります。 Lockを保持している間にスレッドが終了すると、Lockの動作は未定義になります。

Caution

コード パス上で、スレッドが終了する前に複数のロックを入力する可能性がある場合は、同じスレッドで 2 つのロックを入力するすべてのコード パスが同じ順序で入力されるようにします。 そうしないと、デッドロックにつながる可能性があります。 たとえば、1 つのコード パス スレッド T1 ロック L1 、両方を終了する前に L2 ロックし、別のコード パス スレッドでは両方のロックを逆の順序で入力 T2 考えてみます。 そのシナリオでは、次の順序のイベントが発生する可能性があります。T1は、L1を入力T2L2を入力T1L2を入力して待機、L1を入力して待機T2。 解決できない T1T2 の間にデッドロックがあり、将来いずれかのロックを入力しようとする他のスレッドもハングします。

コンストラクター

名前 説明
Lock()

Lock クラスの新しいインスタンスを初期化します。

プロパティ

名前 説明
IsHeldByCurrentThread

ロックが現在のスレッドによって保持されているかどうかを示す値を取得します。

メソッド

名前 説明
Enter()

ロックを入力し、必要に応じてロックを入力するまで待機します。

EnterScope()

ロックを入力し、必要に応じてロックを入力するまで待機します。

Equals(Object)

指定されたオブジェクトが現在のオブジェクトと等しいかどうかを判断します。

(継承元 Object)
Exit()

ロックを終了します。

GetHashCode()

既定のハッシュ関数として機能します。

(継承元 Object)
GetType()

現在のインスタンスの Type を取得します。

(継承元 Object)
MemberwiseClone()

現在の Objectの簡易コピーを作成します。

(継承元 Object)
ToString()

現在のオブジェクトを表す文字列を返します。

(継承元 Object)
TryEnter()

待機せずにロックの入力を試みます。

TryEnter(Int32)

ロックの入力を試み、必要に応じて、ロックを入力できるようになるまで、指定したミリ秒数待機します。

TryEnter(TimeSpan)

ロックの入力を試み、必要に応じてロックを入力するか、指定されたタイムアウトの有効期限が切れるまで待機します。

適用対象