Est-il valide de partager une instance de la Random
classe entre plusieurs threads? Et pour appeler à nextInt(int)
partir de plusieurs threads en particulier?
java
multithreading
random
thread-safety
Shcheklein
la source
la source
java.util.concurrent.ThreadLocalRandom
.Réponses:
Il est thread-safe dans le sens où il génère toujours des nombres aléatoires lorsqu'il est utilisé par plusieurs threads.
L'implémentation de la JVM Sun / Oracle utilise synchronized et AtomicLong comme amorce pour améliorer la cohérence entre les threads. Mais cela ne semble pas être garanti sur toutes les plates-formes dans la documentation.
Je n'écrirais pas votre programme pour exiger une telle garantie, d'autant plus que vous ne pouvez pas déterminer l'ordre dans lequel
nextInt()
sera appelé.la source
C'est thread-safe, bien que ce ne soit pas toujours le cas.
Voir http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6362070 pour plus de détails.
la source
Selon la documentation, Math.random () garantit qu'il est sûr pour une utilisation par plusieurs threads. Mais pas la classe Random. Je suppose que vous devrez alors synchroniser cela vous-même.
la source
Oui, Random est thread-safe. la
nextInt()
méthode appelle lanext(int)
méthode protégée qui utiliseAtomicLong seed, nextseed
(atomic long) pour générer une graine suivante.AtomicLong
est utilisé pour la sécurité des threads lors de la génération de semences.la source
Comme dit, il s'agit d'une sauvegarde de thread, mais il peut être judicieux d'utiliser
java.util.concurrent.ThreadLocalRandom
selon cet article (lien mort). ThreadLocalRandom est également une sous-classe de Random, il est donc rétrocompatible.la source
Il n'y a aucune raison pour laquelle plusieurs threads ne peuvent pas tous utiliser le même Random. Cependant, puisque la classe n'est pas explicitement thread-safe et maintient une séquence de nombres pseudo-aléatoires via la graine. Plusieurs threads peuvent se retrouver avec le même nombre aléatoire. Il serait préférable de créer plusieurs aléas pour chaque thread et de les semer différemment.
EDIT : Je viens de remarquer que l'implémentation Sun utilise AtomicLong, donc je suppose que c'est Thread-safe (comme l'a également noté Peter Lawrey (+1)).
EDIT2 : OpenJDK utilise également AtomicLong pour la graine. Comme d'autres l'ont dit, il n'est toujours pas bon de se fier à cela.
la source
Voici comment j'ai traité le problème sans supposer que Random utilise des variables atomiques. Il peut encore entrer en collision de manière aléatoire si elle
currentTime * thread id
est égale dans le futur, mais c'est assez rare pour mes besoins. Pour vraiment éviter la possibilité de collisions, vous pouvez demander à chaque demande d'attendre un horodatage d'horloge unique.la source
(24*60*60*1000)
partie est -elle significative?(24*60*60*1000)
était de sorte qu'un fil d'ID12
àxxxxxxxxxx045
Millis ne s'ensemencée même comme un fil22
àxxxxxxxxxx035
Millis. Cependant, je n'ai aucune bonne raison de supposer que les ID de threads sont incrémentiels, et il n'y a aucune bonne raison de penser que je crée des threads à des moments plus aléatoires demain qu'aujourd'hui. J'ai simplifié l'alg maintenant et mis à jour la description pour identifier le défaut.La
Random
classe n'est pas configurée pour qu'une instance soit utilisée dans plusieurs threads. Bien sûr, si vous faites cela, vous augmenterez probablement la possibilité de devenir imprévisible et plus proche des nombres aléatoires . Mais comme il s'agit d'un générateur pseudo-aléatoire, je ne vois pas pourquoi vous auriez besoin de partager une instance. Existe-t-il une exigence plus spécifique?la source