2012-04-11 13 views
5

Estoy escribiendo un constructor de clase con un campo decimal, que debe inicializarse con un valor aleatorio. Solo un pequeño campo y necesito crear un nuevo objeto Random. En primer lugar, parece engorroso, y en el segundo puede surgir una gran cantidad de valores iguales, en el caso de crear muchos objetos en un intervalo de tiempo (new Random() es euqal a new Random(System.currentTimeMillis()), e igual tiempoMillis implica iguales valores aleatorios).Obtener valor aleatorio sin crear el objeto `Random`

¿Cuál es la mejor manera de evitar esto?

+0

He intentado encontrar una solución en 'DatagramSocket()' (necesita un valor de socket aleatorio), pero no tuvo éxito. – Jofsey

+1

¿Qué versión de Java estás usando? –

+0

Estoy usando Java 7. – Jofsey

Respuesta

9

nueva aleatorio() es euqal de nuevo al azar (System.currentTimeMillis())

No, no lo es. En JDK recientes, es new Random(seedUniquifier()^System.nanoTime()); donde seedUniquifier() se basa en ejecutar un generador congruente lineal en un AtomicLong estático. Por lo tanto, es realmente seguro crear objetos Random según sea necesario.

Por supuesto, siempre puede tener un campo private static Random y usarlo en el constructor.

6

Está buscando Math.random. Este es un método estático que inicializa implícitamente un nuevo objeto Random la primera vez que se llama, y ​​luego utiliza ese objeto a partir de entonces. De modo que obtendrá los beneficios de compartir un solo objeto Random entre todas las inicializaciones de campo estático, sin tener que administrar un objeto Random usted mismo.

+1

Tiene la desventaja de no tener una API tan agradable como 'Random'. No hay mucha "gestión" involucrada en un solo campo final estático ... –

+0

Sería genial tener el mismo método para enteros. Hasta entonces, prefiero usar un campo ** static ** 'Random' en mi propia clase. – Jofsey

2

es que usted está utilizando Java 7, Random es multi-hilo, tal como se documenta:

Las instancias de java.util.Random son multi-hilo. Sin embargo, el uso simultáneo de la misma instancia de java.util.Random en los subprocesos puede encontrar conflicto y el consiguiente bajo rendimiento. Considere usar ThreadLocalRandom en diseños multiproceso.

Así que usted puede sólo tiene que utilizar:

private static final Random random = new Random(); 

... ThreadLocalRandom o utilizar si va a utilizar esto desde muchos hilos. Todavía no va a ser tan aleatorio como SecureRandom, por supuesto. Básicamente ajuste su elección de acuerdo a sus necesidades.