Le thread de classe aléatoire est-il sûr?

Est-il valide de partager une instance de la classe Random entre plusieurs threads? Et d’appeler nextInt(int) partir de plusieurs threads en particulier?

    Il est thread-safe dans le sens où il générera toujours des nombres aléatoires lorsqu’il est utilisé par plusieurs threads.

    L’implémentation de la machine virtuelle Java Sun / Oracle utilise la fonction de graine synchronisée et AtomicLong pour améliorer la cohérence entre les threads. Mais cela ne semble pas être garanti sur toutes les plates-formes de 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é.

    Il 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.

    Selon la documentation, Math.random () garantit son utilisation en toute sécurité par plusieurs threads. Mais la classe aléatoire ne le fait pas. Je suppose que vous devrez alors vous synchroniser.

    Oui, Aléatoire est thread-safe. La méthode nextInt() appelle la méthode next(int) protégée qui utilise la AtomicLong 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 des semences.

    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 Randoms pour chaque thread et de les semer différemment.

    EDIT : Je viens de remarquer que l’implémentation de 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 s’en remettre à cela.

    Voici comment j’ai traité le problème sans supposer que Random utilise des variables atomiques. Il peut toujours se heurter aléatoirement si l’ currentTime * thread id est égal à un certain temps dans le futur, mais c’est assez rare pour mes besoins. Pour éviter toute possibilité de collision, vous pouvez attendre que chaque requête attend un horodatage unique.

     /** * Thread-specific random number generators. Each is seeded with the thread * ID, so the sequence of pseudo-random numbers are unique between threads. */ private static ThreadLocal random = new ThreadLocal() { @Override protected Random initialValue() { return new Random( System.currentTimeMillis() * Thread.currentThread().getId()); } }; 

    Comme dit précédemment, il s’agit d’une sauvegarde sur thread, mais il peut être judicieux d’utiliser java.util.concurrent.ThreadLocalRandom conformément à cet article . ThreadLocalRandom est également une sous-classe de Random, donc compatible avec les versions antérieures.

    La classe Random n’est pas configurée pour qu’une instance soit utilisée dans plusieurs threads. Bien sûr, si vous avez fait 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?