Strange Java crop behavior

The following code should create two random objects with the same seeds:

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

Seeds should be the same, since they System.currentTimeMillis()did not change before and after creating two objects, as shown in the output:

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

In documents, a constructor with no arguments is simple:

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

So what gives? Can someone explain why two generators return different outputs when they must have the same seed?

+4
source share
3 answers

If you use java.util.Random, this is the default no-args constructor that I see - now it may depend on the version of JDK you are using (this code seems to be used for solar JDK 6 and 7 to a minimum) :

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

, , (.. public Random { this(System.currentTimeMillis()); } java , , , , . Random (Mac OS X)

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

two generators return different outputs when they must have the same seed?

they make? it seems to me that only one of your generators gets the seed of millis ...

0
source

All Articles