Когда именно Math.random () будет посеян? - PullRequest
1 голос
/ 14 марта 2012

Согласно документации:

Когда этот метод вызывается впервые, он создает один новый генератор псевдослучайных чисел, точно так же, как если бы это выражалось

new java.util.Random

Этот новый генератор псевдослучайных чисел используется после этого для всех вызовов этого метода и больше нигде не используется.

Я запутался в том, что касается "Когда этот метод впервые вызывается" - это когда мое приложение впервые вызывает его? Разве оно когда-либо заполняется только один раз, независимо от того, что делает мое приложение?

Ответы [ 3 ]

2 голосов
/ 14 марта 2012

Инициализируется, когда метод Math.random() вызывается впервые.

Интересно, что в Java 5 и 6 код использует сломанный шаблон двойной проверки-блокировки так что не поточно-ориентирован, даже если выглядит так.

[EDIT] Правильный код будет выглядеть следующим образом:

private static volatile Random randomNumberGenerator; // broken without volatile

или альтернативно, но дороже:

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

[EDIT2] Официальная ошибка: Math.random () / Math.initRNG () использует «двойную проверку блокировки»

0 голосов
/ 14 марта 2012

Когда он впервые вызывается в вашей JVM (любым кодом).

Он выполняет (небезопасно - см. Ссылку ниже) Ленивая инициализация Singleton :

private static Random randomNumberGenerator;

по телефону:

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

РЕДАКТИРОВАТЬ Обратите внимание, что этот код не является потокобезопасным. Официальный баг: http://bugs.sun.com/view_bug.do?bug_id=6470700

0 голосов
/ 14 марта 2012

Глядя на исходный код, соответствующий код для Math.random() определяется как:

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();
}

Таким образом, поскольку randomNumberGenerator является переменной static, после того, как она инициализируется (первый вызов Math.random()) путем вызова ее любым классом в JVM, она остается там (если класс не является больше не требуется и не загружен.

...