22

次の Lock ステートメントがあります。

private readonly object ownerLock_ = new object();

lock (ownerLock_)
{
}

ロック変数にvolatileキーワードを使用する必要がありますか?

private readonly volatile object ownerLock_ = new object();

MSDN では、通常、ロックせずにアクセスされるフィールドに使用されることがわかったので、Lock を使用する場合、volatile を使用する必要はありませんか?

MSDNから:

volatile 修飾子は通常、lock ステートメントを使用してアクセスをシリアル化せずに、複数のスレッドによってアクセスされるフィールドに使用されます。

4

2 に答える 2

20

ロックを所有している間、ロックが「保護」するデータにのみアクセスする場合は、そうです-それらのフィールドを揮発性にすることは不要です。ownerLock_変数を揮発性にする必要もありません。(現在、ステートメント内に実際のコードを示していないため、具体的な言葉で話すのが難しくなっていますが、ステートメント内のデータを実際に読み取ったり変更したりlockしていると思います。)lock

volatileアプリケーション コードで使用されることはほとんどありません。単一の変数へのロックなしのアクセスが必要な場合Interlockedは、ほとんどの場合、理由が簡単です。それ以上のロックなしのアクセスが必要な場合は、ほとんどの場合、ロックを開始します。(または、最初から不変のデータ構造を使用してみてください。)

volatileスレッド化のためのより高いレベルの抽象化を構築しようとしているコード内でのみ見られると思います。たとえば、TPL コードベース内です。これは、.NET メモリ モデルを完全に理解している専門家向けのツールです。

于 2012-07-17T13:02:42.140 に答える
2

何かがあれば、それはreadonlyスレッドセーフです。(まあ、ほとんどです。専門家は、ステートメントでNullReferenceException を取得する方法を理解できるかもしれませんが、簡単ではありません。) 、、またはロックは必要ありません。これはマルチスレッドの理想的なキーワードであり、できる限り使用する必要があります。大きな欠点 (値を変更できない) が問題にならないロック オブジェクトには最適です。lockreadonlyvolatileInterlocked

また、参照は不変ですが、参照されるオブジェクトはそうではない場合があります。「new object()」はここにありますが、それがList変更可能で、スレッドセーフではない場合は、オブジェクトを保持するために参照 (およびそれに対する他のすべての参照) をロックする必要があります一度に 2 つのスレッドで変更します。

于 2012-07-17T17:20:13.017 に答える