jdk/src/share/classes/java/util/Random.java
changeset 5468 c9aa7dfb4f78
parent 4110 ac033ba6ede4
child 5506 202f599c92aa
--- a/jdk/src/share/classes/java/util/Random.java	Sun May 09 00:59:49 2010 -0700
+++ b/jdk/src/share/classes/java/util/Random.java	Sun May 09 16:03:13 2010 -0700
@@ -86,8 +86,23 @@
      * the seed of the random number generator to a value very likely
      * to be distinct from any other invocation of this constructor.
      */
-    public Random() { this(++seedUniquifier + System.nanoTime()); }
-    private static volatile long seedUniquifier = 8682522807148012L;
+    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;
+        }
+    }
+
+    private static final AtomicLong seedUniquifier
+        = new AtomicLong(8682522807148012L);
 
     /**
      * Creates a new random number generator using a single {@code long} seed.
@@ -103,8 +118,11 @@
      * @see   #setSeed(long)
      */
     public Random(long seed) {
-        this.seed = new AtomicLong(0L);
-        setSeed(seed);
+        this.seed = new AtomicLong(initialScramble(seed));
+    }
+
+    private static long initialScramble(long seed) {
+        return (seed ^ multiplier) & mask;
     }
 
     /**
@@ -127,8 +145,7 @@
      * @param seed the initial seed
      */
     synchronized public void setSeed(long seed) {
-        seed = (seed ^ multiplier) & mask;
-        this.seed.set(seed);
+        this.seed.set(initialScramble(seed));
         haveNextNextGaussian = false;
     }