Garantie de sécurité des threads dans la génération de nombres aléatoires C#
Dans les applications multithread, il est crucial de s'assurer que les ressources ou méthodes critiques sont thread-safe. En C#, la sécurité des threads de la méthode Random.Next()
de l'outil de génération de nombres aléatoires couramment utilisé est préoccupante.
Le générateur de nombres aléatoires de C# est-il thread-safe ?
Non, l'utilisation simultanée de Random.Next()
à partir de plusieurs threads en même temps n'est pas thread-safe. Cela peut conduire à un comportement imprévisible et éventuellement à des résultats incorrects. La cause première du problème est que plusieurs threads peuvent tenter de modifier l'état interne de la même Random
instance en même temps, ce qui entraîne une corruption de la valeur, voire un échec complet, ne renvoyant que 0.
Créez un générateur de nombres aléatoires thread-safe
Bien que Random.Next()
lui-même ne soit pas thread-safe, il est possible de créer une version thread-safe sans utiliser un mécanisme de verrouillage complexe pour chaque appel de méthode. En tirant parti d'une technique décrite dans un article externe, nous pouvons implémenter une ThreadSafeRandom
classe personnalisée :
<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>
Explication
La classeThreadSafeRandom
garantit la sécurité des threads en conservant une instance Random
distincte pour chaque thread. Cela empêche les threads d'interférer avec l'état interne de chacun. Cependant, il y a une mise en garde : la création de plusieurs instances de Random
à proximité immédiate (en 15 millisecondes environ) peut entraîner la même séquence de nombres aléatoires. Pour résoudre ce problème, nous introduisons une instance Random
statique globale (_global
) qui est utilisée pour générer la valeur de départ pour l'instance Random
locale (_local
) de chaque thread.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!