gpt4 book ai didi

java - 播种 Java Random 时的奇怪行为

转载 作者:搜寻专家 更新时间:2023-11-01 01:37:04 27 4
gpt4 key购买 nike

以下代码应创建两个具有相同种子的 Random 对象:

System.out.println("System time before: " + System.currentTimeMillis());
Random r1 = new Random();
Random r2 = new Random(System.currentTimeMillis());
System.out.println("System time after: " + System.currentTimeMillis());

System.out.println("r1: " + r1.nextInt());
System.out.println("r2: " + r2.nextInt());

种子应该相同,因为 System.currentTimeMillis() 在创建两个对象之前和之后没有改变,如输出所示:

System time before: 1331889186449
System time after: 1331889186449
r1: -1836225474
r2: 2070673752

根据文档,没有任何参数的构造函数很简单:

public Random() { this(System.currentTimeMillis()); }

那么是什么给了?谁能解释为什么两个生​​成器在它们应该具有相同种子时返回不同的输出?

最佳答案

如果您使用的是 java.util.Random,这是我看到的默认无参数构造函数 - 现在它可能取决于您使用的 JDK 版本(此代码似乎用于 sun JDK 6 & 7最少):

public Random() {
this(seedUniquifier() ^ System.nanoTime());
}

private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}

为了确认这一点,这里有一个代码来检查种子是否相同:

public static void main(String args[]) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
System.out.println("System time before: " + System.currentTimeMillis());
Random r1 = new Random();
Random r2 = new Random(System.currentTimeMillis());
System.out.println("System time after: " + System.currentTimeMillis());

Field seed = Random.class.getDeclaredField("seed");
seed.setAccessible(true);
AtomicLong seed1 = (AtomicLong) seed.get(r1);
AtomicLong seed2 = (AtomicLong) seed.get(r2);

System.out.println("seed1 = " + seed1);
System.out.println("seed2 = " + seed2);
}

关于java - 播种 Java Random 时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9734606/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com