C# 乱数生成におけるスレッドの安全性の保証
マルチスレッドアプリケーションでは、重要なリソースまたはメソッドがスレッドセーフであることを確認することが重要です。 C# では、一般的に使用される乱数生成ツールの Random.Next()
メソッドのスレッド セーフが懸念されます。
C# の乱数生成器はスレッドセーフですか?
いいえ、同時に複数のスレッドから Random.Next()
を同時に使用することはスレッドセーフではありません。これにより、予期しない動作が発生したり、誤った結果が発生したりする可能性があります。この問題の根本原因は、複数のスレッドが同じ Random
インスタンスの内部状態を同時に変更しようとして、値が破損したり、完全に失敗して 0 のみを返したりする可能性があることです。
スレッドセーフな乱数ジェネレーターを作成します
Random.Next()
自体はスレッドセーフではありませんが、メソッド呼び出しごとに複雑なロック機構を使用せずにスレッドセーフなバージョンを作成することは可能です。外部記事で説明されている手法を利用することで、カスタム ThreadSafeRandom
クラスを実装できます:
<code class="language-csharp">public class ThreadSafeRandom { private static readonly Random _global = new Random(); [ThreadStatic] private static Random _local; public int Next() { if (_local == null) { int seed; lock (_global) { seed = _global.Next(); } _local = new Random(seed); } return _local.Next(); } }</code>
説明
ThreadSafeRandom
クラスは、スレッドごとに個別の Random
インスタンスを維持することでスレッドの安全性を確保します。これにより、スレッドが相互の内部状態に干渉するのを防ぎます。ただし、注意点があります。Random
の複数のインスタンスを非常に近接して (約 15 ミリ秒以内に) 作成すると、同じ乱数シーケンスが生成される可能性があります。この問題を解決するために、各スレッドのローカル Random
インスタンス (_global
) のシード値を生成するために使用されるグローバル静的 Random
インスタンス (_local
) を導入します。
以上がC# の `Random.Next()` メソッドはスレッドセーフですか? スレッドセーフな代替メソッドを作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。