emul/compact/src/main/java/java/util/Random.java
changeset 599 d0f57d3ea898
parent 597 ee8a922f4268
     1.1 --- a/emul/compact/src/main/java/java/util/Random.java	Mon Jan 28 13:28:02 2013 +0100
     1.2 +++ b/emul/compact/src/main/java/java/util/Random.java	Mon Jan 28 13:52:28 2013 +0100
     1.3 @@ -24,9 +24,8 @@
     1.4   */
     1.5  
     1.6  package java.util;
     1.7 -import java.io.*;
     1.8 -import java.util.concurrent.atomic.AtomicLong;
     1.9 -import sun.misc.Unsafe;
    1.10 +
    1.11 +import org.apidesign.bck2brwsr.emul.lang.System;
    1.12  
    1.13  /**
    1.14   * An instance of this class is used to generate a stream of
    1.15 @@ -75,7 +74,7 @@
    1.16       * (The specs for the methods in this class describe the ongoing
    1.17       * computation of this value.)
    1.18       */
    1.19 -    private final AtomicLong seed;
    1.20 +    private long seed;
    1.21  
    1.22      private static final long multiplier = 0x5DEECE66DL;
    1.23      private static final long addend = 0xBL;
    1.24 @@ -89,20 +88,17 @@
    1.25      public Random() {
    1.26          this(seedUniquifier() ^ System.nanoTime());
    1.27      }
    1.28 -
    1.29 -    private static long seedUniquifier() {
    1.30 +    
    1.31 +    private static synchronized long seedUniquifier() {
    1.32          // L'Ecuyer, "Tables of Linear Congruential Generators of
    1.33          // Different Sizes and Good Lattice Structure", 1999
    1.34 -        for (;;) {
    1.35 -            long current = seedUniquifier.get();
    1.36 -            long next = current * 181783497276652981L;
    1.37 -            if (seedUniquifier.compareAndSet(current, next))
    1.38 -                return next;
    1.39 -        }
    1.40 +        long current = seedUniquifier;
    1.41 +        long next = current * 181783497276652981L;
    1.42 +        seedUniquifier = next;
    1.43 +        return next;
    1.44      }
    1.45  
    1.46 -    private static final AtomicLong seedUniquifier
    1.47 -        = new AtomicLong(8682522807148012L);
    1.48 +    private static long seedUniquifier = 8682522807148012L;
    1.49  
    1.50      /**
    1.51       * Creates a new random number generator using a single {@code long} seed.
    1.52 @@ -118,7 +114,7 @@
    1.53       * @see   #setSeed(long)
    1.54       */
    1.55      public Random(long seed) {
    1.56 -        this.seed = new AtomicLong(initialScramble(seed));
    1.57 +        this.seed = initialScramble(seed);
    1.58      }
    1.59  
    1.60      private static long initialScramble(long seed) {
    1.61 @@ -145,7 +141,7 @@
    1.62       * @param seed the initial seed
    1.63       */
    1.64      synchronized public void setSeed(long seed) {
    1.65 -        this.seed.set(initialScramble(seed));
    1.66 +        this.seed = initialScramble(seed);
    1.67          haveNextNextGaussian = false;
    1.68      }
    1.69  
    1.70 @@ -174,13 +170,12 @@
    1.71       *         generator's sequence
    1.72       * @since  1.1
    1.73       */
    1.74 -    protected int next(int bits) {
    1.75 +    protected synchronized int next(int bits) {
    1.76          long oldseed, nextseed;
    1.77 -        AtomicLong seed = this.seed;
    1.78 -        do {
    1.79 -            oldseed = seed.get();
    1.80 -            nextseed = (oldseed * multiplier + addend) & mask;
    1.81 -        } while (!seed.compareAndSet(oldseed, nextseed));
    1.82 +        long seed = this.seed;
    1.83 +        oldseed = seed;
    1.84 +        nextseed = (oldseed * multiplier + addend) & mask;
    1.85 +        this.seed = nextseed;
    1.86          return (int)(nextseed >>> (48 - bits));
    1.87      }
    1.88  
    1.89 @@ -499,77 +494,10 @@
    1.90                  v2 = 2 * nextDouble() - 1; // between -1 and 1
    1.91                  s = v1 * v1 + v2 * v2;
    1.92              } while (s >= 1 || s == 0);
    1.93 -            double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
    1.94 +            double multiplier = Math.sqrt(-2 * Math.log(s)/s);
    1.95              nextNextGaussian = v2 * multiplier;
    1.96              haveNextNextGaussian = true;
    1.97              return v1 * multiplier;
    1.98          }
    1.99      }
   1.100 -
   1.101 -    /**
   1.102 -     * Serializable fields for Random.
   1.103 -     *
   1.104 -     * @serialField    seed long
   1.105 -     *              seed for random computations
   1.106 -     * @serialField    nextNextGaussian double
   1.107 -     *              next Gaussian to be returned
   1.108 -     * @serialField      haveNextNextGaussian boolean
   1.109 -     *              nextNextGaussian is valid
   1.110 -     */
   1.111 -    private static final ObjectStreamField[] serialPersistentFields = {
   1.112 -        new ObjectStreamField("seed", Long.TYPE),
   1.113 -        new ObjectStreamField("nextNextGaussian", Double.TYPE),
   1.114 -        new ObjectStreamField("haveNextNextGaussian", Boolean.TYPE)
   1.115 -    };
   1.116 -
   1.117 -    /**
   1.118 -     * Reconstitute the {@code Random} instance from a stream (that is,
   1.119 -     * deserialize it).
   1.120 -     */
   1.121 -    private void readObject(java.io.ObjectInputStream s)
   1.122 -        throws java.io.IOException, ClassNotFoundException {
   1.123 -
   1.124 -        ObjectInputStream.GetField fields = s.readFields();
   1.125 -
   1.126 -        // The seed is read in as {@code long} for
   1.127 -        // historical reasons, but it is converted to an AtomicLong.
   1.128 -        long seedVal = fields.get("seed", -1L);
   1.129 -        if (seedVal < 0)
   1.130 -          throw new java.io.StreamCorruptedException(
   1.131 -                              "Random: invalid seed");
   1.132 -        resetSeed(seedVal);
   1.133 -        nextNextGaussian = fields.get("nextNextGaussian", 0.0);
   1.134 -        haveNextNextGaussian = fields.get("haveNextNextGaussian", false);
   1.135 -    }
   1.136 -
   1.137 -    /**
   1.138 -     * Save the {@code Random} instance to a stream.
   1.139 -     */
   1.140 -    synchronized private void writeObject(ObjectOutputStream s)
   1.141 -        throws IOException {
   1.142 -
   1.143 -        // set the values of the Serializable fields
   1.144 -        ObjectOutputStream.PutField fields = s.putFields();
   1.145 -
   1.146 -        // The seed is serialized as a long for historical reasons.
   1.147 -        fields.put("seed", seed.get());
   1.148 -        fields.put("nextNextGaussian", nextNextGaussian);
   1.149 -        fields.put("haveNextNextGaussian", haveNextNextGaussian);
   1.150 -
   1.151 -        // save them
   1.152 -        s.writeFields();
   1.153 -    }
   1.154 -
   1.155 -    // Support for resetting seed while deserializing
   1.156 -    private static final Unsafe unsafe = Unsafe.getUnsafe();
   1.157 -    private static final long seedOffset;
   1.158 -    static {
   1.159 -        try {
   1.160 -            seedOffset = unsafe.objectFieldOffset
   1.161 -                (Random.class.getDeclaredField("seed"));
   1.162 -        } catch (Exception ex) { throw new Error(ex); }
   1.163 -    }
   1.164 -    private void resetSeed(long seedVal) {
   1.165 -        unsafe.putObjectVolatile(this, seedOffset, new AtomicLong(seedVal));
   1.166 -    }
   1.167  }