Flash
Flash

Reputation: 16713

Exactly when is Math.random() seeded?

According to the documentation:

When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression

new java.util.Random

This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.

I'm confused as to the scope of 'When this method is first called" - is it when my application first calls it? Is it only ever seeded once no matter what my application does?

Upvotes: 1

Views: 223

Answers (3)

Bohemian
Bohemian

Reputation: 425073

When it is first called in your JVM (by any code).

It's doing an (unsafe - see link below) lazy initialization of a singleton:

private static Random randomNumberGenerator;

by calling:

private static synchronized void initRNG() {
    if (randomNumberGenerator == null) 
        randomNumberGenerator = new Random();
}

EDIT Note that this code is not thread safe. Official bug: https://bugs.java.com/bugdatabase/view_bug?bug_id=6470700

Upvotes: 0

Aaron Digulla
Aaron Digulla

Reputation: 328624

It's initialized when the method Math.random() is called for the first time.

Interestingly enough, in Java 5 and 6, the code uses the broken double-checked-locking pattern, so it's not thread safe even though it looks like it is.

[EDIT] The correct code would look like this:

private static volatile Random randomNumberGenerator; // broken without volatile

or alternatively but more expensive:

public static synchronized double random() {
    ...
}

[EDIT2] Official bug: Math.random() / Math.initRNG() uses "double checked locking"

Upvotes: 2

beny23
beny23

Reputation: 35018

Looking at the source code, the pertinent code for Math.random() is defined as:

private static Random randomNumberGenerator;

private static synchronized void initRNG() {
    if (randomNumberGenerator == null) 
        randomNumberGenerator = new Random();
}

public static double random() {
    if (randomNumberGenerator == null) initRNG();
    return randomNumberGenerator.nextDouble();
}

So, as randomNumberGenerator is a static variable, once it is initialised (the first call to Math.random()) by a call to it by any class in the JVM, it stays there (unless the class is no longer needed and unloaded.

Upvotes: 0

Related Questions