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 }