ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Random.java
(Generate patch)

Comparing jsr166/src/main/java/util/Random.java (file contents):
Revision 1.2 by tim, Fri Aug 8 20:05:07 2003 UTC vs.
Revision 1.4 by jsr166, Fri Nov 7 01:36:42 2003 UTC

# Line 1 | Line 1
1   /*
2 < * @(#)Random.java      1.38 02/03/04
2 > * %W% %E%
3   *
4 < * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
4 > * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
5   * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6   */
7  
8   package java.util;
9   import java.io.*;
10 < import sun.misc.Unsafe;
10 > import java.util.concurrent.atomic.AtomicLong;
11  
12   /**
13   * An instance of this class is used to generate a stream of
# Line 33 | Line 33 | import sun.misc.Unsafe;
33   * class <code>Math</code> simpler to use.
34   *
35   * @author  Frank Yellin
36 < * @version 1.38, 03/04/02
36 > * @version %I%, %G%
37   * @see     java.lang.Math#random()
38   * @since   JDK1.0
39   */
# Line 42 | Line 42 | class Random implements java.io.Serializ
42      /** use serialVersionUID from JDK 1.1 for interoperability */
43      static final long serialVersionUID = 3905348978240129619L;
44  
45    // Setup to use Unsafe.compareAndSwapLong to update seed.
46    private static final Unsafe unsafe =  Unsafe.getUnsafe();
47    private static final long seedOffset;
48    static {
49      try {
50        seedOffset =
51          unsafe.objectFieldOffset(Random.class.getDeclaredField("seed"));
52      } catch(Exception ex) { throw new Error(ex); }
53    }
54
45      /**
46       * The internal state associated with this pseudorandom number generator.
47       * (The specs for the methods in this class describe the ongoing
# Line 59 | Line 49 | class Random implements java.io.Serializ
49       *
50       * @serial
51       */
52 <    private volatile long seed;
52 >    private AtomicLong seed;
53  
54      private final static long multiplier = 0x5DEECE66DL;
55      private final static long addend = 0xBL;
56      private final static long mask = (1L << 48) - 1;
57  
58 <    /**
59 <     * Creates a new random number generator. Its seed is initialized to
60 <     * a value based on the current time:
61 <     * <blockquote><pre>
72 <     * public Random() { this(System.currentTimeMillis()); }</pre></blockquote>
73 <     * Two Random objects created within the same millisecond will have
74 <     * the same sequence of random numbers.
75 <     *
76 <     * @see     java.lang.System#currentTimeMillis()
58 >    /**
59 >     * Creates a new random number generator. This constructor sets
60 >     * the seed of the random number generator to a value very likely
61 >     * to be distinct from any other invocation of this constructor.
62       */
63 <    public Random() { this(System.currentTimeMillis()); }
63 >    public Random() { this(++seedUniquifier + System.nanoTime()); }
64 >    private static volatile long seedUniquifier = 8682522807148012L;
65  
66      /**
67       * Creates a new random number generator using a single
# Line 89 | Line 75 | class Random implements java.io.Serializ
75       * @see     java.util.Random#setSeed(long)
76       */
77      public Random(long seed) {
78 +        this.seed = new AtomicLong(0L);
79          setSeed(seed);
80      }
81  
# Line 109 | Line 96 | class Random implements java.io.Serializ
96       * an overriding method may use all 64 bits of the long argument
97       * as a seed value.
98       *
99 <     * Note: Even though seed is updated atomically, this method
99 >     * Note: Although the seed value is an AtomicLong, this method
100       *       must still be synchronized to ensure correct semantics
101       *       of haveNextNextGaussian.
102       *
103       * @param   seed   the initial seed.
104       */
105      synchronized public void setSeed(long seed) {
106 <        this.seed = (seed ^ multiplier) & mask;
106 >        seed = (seed ^ multiplier) & mask;
107 >        this.seed.set(seed);
108          haveNextNextGaussian = false;
109      }
110  
# Line 147 | Line 135 | class Random implements java.io.Serializ
135      protected int next(int bits) {
136          long oldseed, nextseed;
137          do {
138 <          oldseed = seed;
138 >          oldseed = seed.get();
139            nextseed = (oldseed * multiplier + addend) & mask;
140 <        } while (!unsafe.compareAndSwapLong(this, seedOffset,
153 <                                           oldseed, nextseed));
140 >        } while (!seed.compareAndSet(oldseed, nextseed));
141          return (int)(nextseed >>> (48 - bits));
142      }
143  
# Line 486 | Line 473 | class Random implements java.io.Serializ
473          if (seedVal < 0)
474            throw new java.io.StreamCorruptedException(
475                                "Random: invalid seed");
476 <        seed = seedVal;
476 >        seed = new AtomicLong(seedVal);
477          nextNextGaussian = fields.get("nextNextGaussian", 0.0);
478          haveNextNextGaussian = fields.get("haveNextNextGaussian", false);
479      }
# Line 501 | Line 488 | class Random implements java.io.Serializ
488      synchronized private void writeObject(ObjectOutputStream s) throws IOException {
489          // set the values of the Serializable fields
490          ObjectOutputStream.PutField fields = s.putFields();
491 <        fields.put("seed", seed);
491 >        fields.put("seed", seed.get());
492          fields.put("nextNextGaussian", nextNextGaussian);
493          fields.put("haveNextNextGaussian", haveNextNextGaussian);
494  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines