2

これは、コンセプトの質問の検証です。ここでSOで受け入れられる質問のルールに違反していないことを願っています。回答スレッドにコメントしようとしましたが、そうすることが許可されていません。

この質問に対する受け入れられた回答から導き出します。これは私も持っていた質問です-非ブロッキングロック

受け入れられた回答のオプション2は次のとおりです。

private int _inUseCount;

public void MyMethod()
{
    if (Interlocked.Increment(ref _inUseCount) == 1)
    {
        // do some stuff    
    }
    Interlocked.Decrement(ref _inUseCount);
}

インクリメントを行うスレッドは、必ずしもコードの「//何かを行う」部分を実行するスレッドであるとは限りません。

次のシナリオを検討してください。

  • ThreadA は _inUseCount を 1 にインクリメントし、中断します
  • ThreadB は _inUseCount を 2 に増やして中断します
  • ThreadA は再開し、_inUseCount が 2 に等しいことを確認し、コードの「何かを実行する」部分を実行せず、_inUseCount を 1 にデクリメントして終了します。
  • ThreadB が再開し、_inUseCount が 1 であることを確認し、コードの「何かを行う」部分を実行します。

そして、このパラダイムを使用して、インクリメントを行うスレッドがコードを実行するスレッドであることを確認する方法はありますか?

4

1 に答える 1

4

インクリメントを行うスレッドは、必ずしも「//do some stuff」を実行するスレッドであるとは限りません。

それは間違いです。それらは 1 つのコード パスの一部であり、同じスレッドで実行されます。

しかし、スレッドが_inUseCount==0開始時に見つかった場合にのみ、「いくつかのもの」を実行します。それ以外の場合は、その部分をスキップします。


次のシナリオを検討してください。

  • ThreadA は _inUseCount を 1 にインクリメントし、中断します
  • ThreadA は再開し、_inUseCount が 2 に等しいことを確認し、コードの「何かを実行する」部分を実行せず、_inUseCount を 1 にデクリメントして終了します。

ThreadA が実行され、この Thread が自身の Increment が行ったことを戻り値として参照することif (Interlocked.Increment(ref _inUseCount) == 1)は、この Thread のコントラクトです。Interlocked.Increment()

そのため、 「ThreadA が再開し、inUseCount が 2 に等しいことを確認する」ことは可能ですが、これはコードが行うことではありません。Increment()サスペンド/レジュームのシナリオに依存しない andの戻り値を調べます。

于 2013-07-18T07:07:49.997 に答える