¿Es válido compartir una instancia de la Random
clase entre varios subprocesos? ¿Y para llamar nextInt(int)
desde múltiples hilos en particular?
java
multithreading
random
thread-safety
Shcheklein
fuente
fuente
java.util.concurrent.ThreadLocalRandom
.Respuestas:
Es seguro para subprocesos en el sentido de que aún generará números aleatorios cuando sea utilizado por varios subprocesos.
La implementación de Sun / Oracle JVM utiliza sincronizados y AtomicLong como semilla para mejorar la coherencia entre los subprocesos. Pero no parece estar garantizado en todas las plataformas en la documentación.
No escribiría su programa para requerir tal garantía, especialmente porque no puede determinar el orden en el que
nextInt()
se llamará.fuente
Es seguro para subprocesos, aunque no siempre lo fue.
Consulte http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6362070 para obtener más detalles.
fuente
Según la documentación, Math.random () garantiza que es seguro para su uso por varios subprocesos. Pero la clase Random no lo hace. Supongo que entonces tendrás que sincronizarlo tú mismo.
fuente
Sí, Random es seguro para subprocesos. el
nextInt()
método llama alnext(int)
método protegido que usaAtomicLong seed, nextseed
(atomic long) para generar una siguiente semilla.AtomicLong
se utiliza para la seguridad de subprocesos en la generación de semillas.fuente
Como se dijo, se guarda en subprocesos, pero puede ser aconsejable usarlo de
java.util.concurrent.ThreadLocalRandom
acuerdo con este artículo (enlace muerto). ThreadLocalRandom también es una subclase de Random, por lo que es compatible con versiones anteriores.fuente
No hay ninguna razón por la que varios subprocesos no puedan usar el mismo Random. Sin embargo, dado que la clase no es explícitamente segura para subprocesos y mantiene una secuencia de números pseudoaleatorios a través de la semilla. Varios subprocesos pueden terminar con el mismo número aleatorio. Sería mejor crear varios Randoms para cada hilo y sembrarlos de manera diferente.
EDITAR : Acabo de notar que la implementación de Sun usa AtomicLong, así que supongo que es seguro para subprocesos (como también lo señaló Peter Lawrey (+1)).
EDIT2 : OpenJDK también usa AtomicLong para la semilla. Como han dicho otros, todavía no es bueno confiar en esto.
fuente
Así es como manejé el problema sin asumir que Random usa variables atómicas. Todavía puede colisionar aleatoriamente si
currentTime * thread id
es igual en algún momento en el futuro, pero eso es lo suficientemente raro para mis necesidades. Para evitar realmente la posibilidad de colisiones, puede hacer que cada solicitud espere una marca de tiempo de reloj única.fuente
(24*60*60*1000)
parte significativa?(24*60*60*1000)
fue que un hilo con ID12
enxxxxxxxxxx045
millis no se sembró de la misma manera que un hilo22
enxxxxxxxxxx035
millis. Sin embargo, no tengo ninguna buena razón para suponer que los ID de subprocesos son incrementales, y no hay una buena razón para pensar que estoy creando subprocesos en momentos más aleatorios mañana que hoy. Simplifiqué el alg ahora y actualicé la descripción para identificar la deficiencia.La
Random
clase no está configurada para que una instancia se utilice en varios subprocesos. Por supuesto, si hizo esto, probablemente aumentará la posibilidad de volverse impredecible y más cercano a números aleatorios . Pero dado que es un generador pseudoaleatorio, no veo por qué necesitarías compartir una instancia. ¿Existe algún requisito más específico?fuente