Java的随机数生成器-是否正在为每个随机数创建一个新的随机对象(功能上)不正确?

dev*_*ium 5 java random

下面的代码是否有可能在控制台上打印一些内容?

while (true) {
    long t1 = System.nanoTime();
    long t2 = System.nanoTime();
    if (t1 == t2)
        System.out.println(t1 == t2);
}
Run Code Online (Sandbox Code Playgroud)

然后呢:

Random r1 = new Random();
Random r2 = new Random();
Run Code Online (Sandbox Code Playgroud)

r1和r2具有相同的种子?

提出相同问题的另一种方法是:以下代码正确吗?

// generate k random integers
int[] random_numbers = new int[k];
for (int i = 0; i < k; ++i) {
  Random r = new Random();
  random_numbers[i] = r.nextInt();
}
Run Code Online (Sandbox Code Playgroud)

编辑:新的Random()的可能实现是:

public Random() {
    this(seedUniquifier() ^ System.nanoTime());
}
Run Code Online (Sandbox Code Playgroud)

实际上,这正是HotSpot的实现。

JB *_*zet 4

System.nanoTime() 的 javadoc 说:

此方法提供纳秒精度,但不一定是纳秒分辨率(即值更改的频率) - 除了分辨率至少与 currentTimeMillis() 一样好之外,不做任何保证。

所以是的,两次连续调用有可能产生相同的值。

但这与第二部分无关:纳米时间不用于播种新的随机数。随机构造函数 javadoc 说:

创建一个新的随机数生成器。此构造函数将随机数生成器的种子设置为一个很可能与此构造函数的任何其他调用不同的值。

因此,连续创建的两个 Random 不太可能具有相同的种子,从而产生相同的随机数。

这并不意味着每次需要时重新创建随机数是一个好主意。Random 的 javadoc 说:

此类的实例用于生成伪随机数流

因此,您可以重复使用同一个实例:它会更快,并且会生成随机数流。

因此,您的所有问题只需阅读 javadoc 即可得到解答。