--- a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java Thu Nov 14 12:36:46 2019 -0400
+++ b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java Thu Nov 14 12:39:49 2019 -0400
@@ -31,6 +31,9 @@
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
+ *
+ * Additional modifications by Guy Steele in 2019 to refactor the code
+ * and to implement the {@link RandomGenerator} interface.
*/
package java.util.concurrent;
@@ -41,13 +44,7 @@
import java.util.Spliterator;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.DoubleConsumer;
-import java.util.function.IntConsumer;
-import java.util.function.LongConsumer;
-import java.util.stream.DoubleStream;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-import java.util.stream.StreamSupport;
+import java.util.random.RandomSupport;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
@@ -123,19 +120,12 @@
* SplittableRandom, that were in part derived from a previous
* version of this class.
*
- * The nextLocalGaussian ThreadLocal supports the very rarely used
- * nextGaussian method by providing a holder for the second of a
- * pair of them. As is true for the base class version of this
- * method, this time/space tradeoff is probably never worthwhile,
- * but we provide identical statistical properties.
+ * This implementation of ThreadLocalRandom overrides the
+ * definition of the nextGaussian() method in the class Random,
+ * and instead uses the ziggurat-based algorithm that is the
+ * default for the RandomGenerator interface.
*/
- private static long mix64(long z) {
- z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
- z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
- return z ^ (z >>> 33);
- }
-
private static int mix32(long z) {
z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
@@ -162,7 +152,7 @@
static final void localInit() {
int p = probeGenerator.addAndGet(PROBE_INCREMENT);
int probe = (p == 0) ? 1 : p; // skip 0
- long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
+ long seed = RandomSupport.mixMurmur64(seeder.getAndAdd(SEEDER_INCREMENT));
Thread t = Thread.currentThread();
U.putLong(t, SEED, seed);
U.putInt(t, PROBE, probe);
@@ -212,82 +202,6 @@
}
/**
- * The form of nextLong used by LongStream Spliterators. If
- * origin is greater than bound, acts as unbounded form of
- * nextLong, else as bounded form.
- *
- * @param origin the least value, unless greater than bound
- * @param bound the upper bound (exclusive), must not equal origin
- * @return a pseudorandom value
- */
- final long internalNextLong(long origin, long bound) {
- long r = mix64(nextSeed());
- if (origin < bound) {
- long n = bound - origin, m = n - 1;
- if ((n & m) == 0L) // power of two
- r = (r & m) + origin;
- else if (n > 0L) { // reject over-represented candidates
- for (long u = r >>> 1; // ensure nonnegative
- u + m - (r = u % n) < 0L; // rejection check
- u = mix64(nextSeed()) >>> 1) // retry
- ;
- r += origin;
- }
- else { // range not representable as long
- while (r < origin || r >= bound)
- r = mix64(nextSeed());
- }
- }
- return r;
- }
-
- /**
- * The form of nextInt used by IntStream Spliterators.
- * Exactly the same as long version, except for types.
- *
- * @param origin the least value, unless greater than bound
- * @param bound the upper bound (exclusive), must not equal origin
- * @return a pseudorandom value
- */
- final int internalNextInt(int origin, int bound) {
- int r = mix32(nextSeed());
- if (origin < bound) {
- int n = bound - origin, m = n - 1;
- if ((n & m) == 0)
- r = (r & m) + origin;
- else if (n > 0) {
- for (int u = r >>> 1;
- u + m - (r = u % n) < 0;
- u = mix32(nextSeed()) >>> 1)
- ;
- r += origin;
- }
- else {
- while (r < origin || r >= bound)
- r = mix32(nextSeed());
- }
- }
- return r;
- }
-
- /**
- * The form of nextDouble used by DoubleStream Spliterators.
- *
- * @param origin the least value, unless greater than bound
- * @param bound the upper bound (exclusive), must not equal origin
- * @return a pseudorandom value
- */
- final double internalNextDouble(double origin, double bound) {
- double r = (nextLong() >>> 11) * DOUBLE_UNIT;
- if (origin < bound) {
- r = r * (bound - origin) + origin;
- if (r >= bound) // correct for rounding
- r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
- }
- return r;
- }
-
- /**
* Returns a pseudorandom {@code int} value.
*
* @return a pseudorandom {@code int} value
@@ -297,622 +211,14 @@
}
/**
- * Returns a pseudorandom {@code int} value between zero (inclusive)
- * and the specified bound (exclusive).
- *
- * @param bound the upper bound (exclusive). Must be positive.
- * @return a pseudorandom {@code int} value between zero
- * (inclusive) and the bound (exclusive)
- * @throws IllegalArgumentException if {@code bound} is not positive
- */
- public int nextInt(int bound) {
- if (bound <= 0)
- throw new IllegalArgumentException(BAD_BOUND);
- int r = mix32(nextSeed());
- int m = bound - 1;
- if ((bound & m) == 0) // power of two
- r &= m;
- else { // reject over-represented candidates
- for (int u = r >>> 1;
- u + m - (r = u % bound) < 0;
- u = mix32(nextSeed()) >>> 1)
- ;
- }
- return r;
- }
-
- /**
- * Returns a pseudorandom {@code int} value between the specified
- * origin (inclusive) and the specified bound (exclusive).
- *
- * @param origin the least value returned
- * @param bound the upper bound (exclusive)
- * @return a pseudorandom {@code int} value between the origin
- * (inclusive) and the bound (exclusive)
- * @throws IllegalArgumentException if {@code origin} is greater than
- * or equal to {@code bound}
- */
- public int nextInt(int origin, int bound) {
- if (origin >= bound)
- throw new IllegalArgumentException(BAD_RANGE);
- return internalNextInt(origin, bound);
- }
-
- /**
* Returns a pseudorandom {@code long} value.
*
* @return a pseudorandom {@code long} value
*/
public long nextLong() {
- return mix64(nextSeed());
- }
-
- /**
- * Returns a pseudorandom {@code long} value between zero (inclusive)
- * and the specified bound (exclusive).
- *
- * @param bound the upper bound (exclusive). Must be positive.
- * @return a pseudorandom {@code long} value between zero
- * (inclusive) and the bound (exclusive)
- * @throws IllegalArgumentException if {@code bound} is not positive
- */
- public long nextLong(long bound) {
- if (bound <= 0)
- throw new IllegalArgumentException(BAD_BOUND);
- long r = mix64(nextSeed());
- long m = bound - 1;
- if ((bound & m) == 0L) // power of two
- r &= m;
- else { // reject over-represented candidates
- for (long u = r >>> 1;
- u + m - (r = u % bound) < 0L;
- u = mix64(nextSeed()) >>> 1)
- ;
- }
- return r;
- }
-
- /**
- * Returns a pseudorandom {@code long} value between the specified
- * origin (inclusive) and the specified bound (exclusive).
- *
- * @param origin the least value returned
- * @param bound the upper bound (exclusive)
- * @return a pseudorandom {@code long} value between the origin
- * (inclusive) and the bound (exclusive)
- * @throws IllegalArgumentException if {@code origin} is greater than
- * or equal to {@code bound}
- */
- public long nextLong(long origin, long bound) {
- if (origin >= bound)
- throw new IllegalArgumentException(BAD_RANGE);
- return internalNextLong(origin, bound);
- }
-
- /**
- * Returns a pseudorandom {@code double} value between zero
- * (inclusive) and one (exclusive).
- *
- * @return a pseudorandom {@code double} value between zero
- * (inclusive) and one (exclusive)
- */
- public double nextDouble() {
- return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
- }
-
- /**
- * Returns a pseudorandom {@code double} value between 0.0
- * (inclusive) and the specified bound (exclusive).
- *
- * @param bound the upper bound (exclusive). Must be positive.
- * @return a pseudorandom {@code double} value between zero
- * (inclusive) and the bound (exclusive)
- * @throws IllegalArgumentException if {@code bound} is not positive
- */
- public double nextDouble(double bound) {
- if (!(bound > 0.0))
- throw new IllegalArgumentException(BAD_BOUND);
- double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
- return (result < bound) ? result : // correct for rounding
- Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
- }
-
- /**
- * Returns a pseudorandom {@code double} value between the specified
- * origin (inclusive) and bound (exclusive).
- *
- * @param origin the least value returned
- * @param bound the upper bound (exclusive)
- * @return a pseudorandom {@code double} value between the origin
- * (inclusive) and the bound (exclusive)
- * @throws IllegalArgumentException if {@code origin} is greater than
- * or equal to {@code bound}
- */
- public double nextDouble(double origin, double bound) {
- if (!(origin < bound))
- throw new IllegalArgumentException(BAD_RANGE);
- return internalNextDouble(origin, bound);
- }
-
- /**
- * Returns a pseudorandom {@code boolean} value.
- *
- * @return a pseudorandom {@code boolean} value
- */
- public boolean nextBoolean() {
- return mix32(nextSeed()) < 0;
- }
-
- /**
- * Returns a pseudorandom {@code float} value between zero
- * (inclusive) and one (exclusive).
- *
- * @return a pseudorandom {@code float} value between zero
- * (inclusive) and one (exclusive)
- */
- public float nextFloat() {
- return (mix32(nextSeed()) >>> 8) * FLOAT_UNIT;
- }
-
- public double nextGaussian() {
- // Use nextLocalGaussian instead of nextGaussian field
- Double d = nextLocalGaussian.get();
- if (d != null) {
- nextLocalGaussian.set(null);
- return d.doubleValue();
- }
- double v1, v2, s;
- do {
- v1 = 2 * nextDouble() - 1; // between -1 and 1
- v2 = 2 * nextDouble() - 1; // between -1 and 1
- s = v1 * v1 + v2 * v2;
- } while (s >= 1 || s == 0);
- double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
- nextLocalGaussian.set(Double.valueOf(v2 * multiplier));
- return v1 * multiplier;
- }
-
- // stream methods, coded in a way intended to better isolate for
- // maintenance purposes the small differences across forms.
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandom {@code int} values.
- *
- * @param streamSize the number of values to generate
- * @return a stream of pseudorandom {@code int} values
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- * @since 1.8
- */
- public IntStream ints(long streamSize) {
- if (streamSize < 0L)
- throw new IllegalArgumentException(BAD_SIZE);
- return StreamSupport.intStream
- (new RandomIntsSpliterator
- (0L, streamSize, Integer.MAX_VALUE, 0),
- false);
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code int}
- * values.
- *
- * @implNote This method is implemented to be equivalent to {@code
- * ints(Long.MAX_VALUE)}.
- *
- * @return a stream of pseudorandom {@code int} values
- * @since 1.8
- */
- public IntStream ints() {
- return StreamSupport.intStream
- (new RandomIntsSpliterator
- (0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
- false);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number
- * of pseudorandom {@code int} values, each conforming to the given
- * origin (inclusive) and bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- * @return a stream of pseudorandom {@code int} values,
- * each with the given origin (inclusive) and bound (exclusive)
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero, or {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- * @since 1.8
- */
- public IntStream ints(long streamSize, int randomNumberOrigin,
- int randomNumberBound) {
- if (streamSize < 0L)
- throw new IllegalArgumentException(BAD_SIZE);
- if (randomNumberOrigin >= randomNumberBound)
- throw new IllegalArgumentException(BAD_RANGE);
- return StreamSupport.intStream
- (new RandomIntsSpliterator
- (0L, streamSize, randomNumberOrigin, randomNumberBound),
- false);
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code
- * int} values, each conforming to the given origin (inclusive) and bound
- * (exclusive).
- *
- * @implNote This method is implemented to be equivalent to {@code
- * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
- *
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- * @return a stream of pseudorandom {@code int} values,
- * each with the given origin (inclusive) and bound (exclusive)
- * @throws IllegalArgumentException if {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- * @since 1.8
- */
- public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
- if (randomNumberOrigin >= randomNumberBound)
- throw new IllegalArgumentException(BAD_RANGE);
- return StreamSupport.intStream
- (new RandomIntsSpliterator
- (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
- false);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandom {@code long} values.
- *
- * @param streamSize the number of values to generate
- * @return a stream of pseudorandom {@code long} values
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- * @since 1.8
- */
- public LongStream longs(long streamSize) {
- if (streamSize < 0L)
- throw new IllegalArgumentException(BAD_SIZE);
- return StreamSupport.longStream
- (new RandomLongsSpliterator
- (0L, streamSize, Long.MAX_VALUE, 0L),
- false);
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code long}
- * values.
- *
- * @implNote This method is implemented to be equivalent to {@code
- * longs(Long.MAX_VALUE)}.
- *
- * @return a stream of pseudorandom {@code long} values
- * @since 1.8
- */
- public LongStream longs() {
- return StreamSupport.longStream
- (new RandomLongsSpliterator
- (0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
- false);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandom {@code long}, each conforming to the given origin
- * (inclusive) and bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- * @return a stream of pseudorandom {@code long} values,
- * each with the given origin (inclusive) and bound (exclusive)
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero, or {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- * @since 1.8
- */
- public LongStream longs(long streamSize, long randomNumberOrigin,
- long randomNumberBound) {
- if (streamSize < 0L)
- throw new IllegalArgumentException(BAD_SIZE);
- if (randomNumberOrigin >= randomNumberBound)
- throw new IllegalArgumentException(BAD_RANGE);
- return StreamSupport.longStream
- (new RandomLongsSpliterator
- (0L, streamSize, randomNumberOrigin, randomNumberBound),
- false);
+ return RandomSupport.mixMurmur64(nextSeed());
}
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code
- * long} values, each conforming to the given origin (inclusive) and bound
- * (exclusive).
- *
- * @implNote This method is implemented to be equivalent to {@code
- * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
- *
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- * @return a stream of pseudorandom {@code long} values,
- * each with the given origin (inclusive) and bound (exclusive)
- * @throws IllegalArgumentException if {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- * @since 1.8
- */
- public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
- if (randomNumberOrigin >= randomNumberBound)
- throw new IllegalArgumentException(BAD_RANGE);
- return StreamSupport.longStream
- (new RandomLongsSpliterator
- (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
- false);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandom {@code double} values, each between zero
- * (inclusive) and one (exclusive).
- *
- * @param streamSize the number of values to generate
- * @return a stream of {@code double} values
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- * @since 1.8
- */
- public DoubleStream doubles(long streamSize) {
- if (streamSize < 0L)
- throw new IllegalArgumentException(BAD_SIZE);
- return StreamSupport.doubleStream
- (new RandomDoublesSpliterator
- (0L, streamSize, Double.MAX_VALUE, 0.0),
- false);
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code
- * double} values, each between zero (inclusive) and one
- * (exclusive).
- *
- * @implNote This method is implemented to be equivalent to {@code
- * doubles(Long.MAX_VALUE)}.
- *
- * @return a stream of pseudorandom {@code double} values
- * @since 1.8
- */
- public DoubleStream doubles() {
- return StreamSupport.doubleStream
- (new RandomDoublesSpliterator
- (0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
- false);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandom {@code double} values, each conforming to the given origin
- * (inclusive) and bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- * @return a stream of pseudorandom {@code double} values,
- * each with the given origin (inclusive) and bound (exclusive)
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero, or {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- * @since 1.8
- */
- public DoubleStream doubles(long streamSize, double randomNumberOrigin,
- double randomNumberBound) {
- if (streamSize < 0L)
- throw new IllegalArgumentException(BAD_SIZE);
- if (!(randomNumberOrigin < randomNumberBound))
- throw new IllegalArgumentException(BAD_RANGE);
- return StreamSupport.doubleStream
- (new RandomDoublesSpliterator
- (0L, streamSize, randomNumberOrigin, randomNumberBound),
- false);
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code
- * double} values, each conforming to the given origin (inclusive) and bound
- * (exclusive).
- *
- * @implNote This method is implemented to be equivalent to {@code
- * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
- *
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- * @return a stream of pseudorandom {@code double} values,
- * each with the given origin (inclusive) and bound (exclusive)
- * @throws IllegalArgumentException if {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- * @since 1.8
- */
- public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
- if (!(randomNumberOrigin < randomNumberBound))
- throw new IllegalArgumentException(BAD_RANGE);
- return StreamSupport.doubleStream
- (new RandomDoublesSpliterator
- (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
- false);
- }
-
- /**
- * Spliterator for int streams. We multiplex the four int
- * versions into one class by treating a bound less than origin as
- * unbounded, and also by treating "infinite" as equivalent to
- * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
- * approach. The long and double versions of this class are
- * identical except for types.
- */
- private static final class RandomIntsSpliterator
- implements Spliterator.OfInt {
- long index;
- final long fence;
- final int origin;
- final int bound;
- RandomIntsSpliterator(long index, long fence,
- int origin, int bound) {
- this.index = index; this.fence = fence;
- this.origin = origin; this.bound = bound;
- }
-
- public RandomIntsSpliterator trySplit() {
- long i = index, m = (i + fence) >>> 1;
- return (m <= i) ? null :
- new RandomIntsSpliterator(i, index = m, origin, bound);
- }
-
- public long estimateSize() {
- return fence - index;
- }
-
- public int characteristics() {
- return (Spliterator.SIZED | Spliterator.SUBSIZED |
- Spliterator.NONNULL | Spliterator.IMMUTABLE);
- }
-
- public boolean tryAdvance(IntConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(ThreadLocalRandom.current().internalNextInt(origin, bound));
- index = i + 1;
- return true;
- }
- return false;
- }
-
- public void forEachRemaining(IntConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- int o = origin, b = bound;
- ThreadLocalRandom rng = ThreadLocalRandom.current();
- do {
- consumer.accept(rng.internalNextInt(o, b));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for long streams.
- */
- private static final class RandomLongsSpliterator
- implements Spliterator.OfLong {
- long index;
- final long fence;
- final long origin;
- final long bound;
- RandomLongsSpliterator(long index, long fence,
- long origin, long bound) {
- this.index = index; this.fence = fence;
- this.origin = origin; this.bound = bound;
- }
-
- public RandomLongsSpliterator trySplit() {
- long i = index, m = (i + fence) >>> 1;
- return (m <= i) ? null :
- new RandomLongsSpliterator(i, index = m, origin, bound);
- }
-
- public long estimateSize() {
- return fence - index;
- }
-
- public int characteristics() {
- return (Spliterator.SIZED | Spliterator.SUBSIZED |
- Spliterator.NONNULL | Spliterator.IMMUTABLE);
- }
-
- public boolean tryAdvance(LongConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(ThreadLocalRandom.current().internalNextLong(origin, bound));
- index = i + 1;
- return true;
- }
- return false;
- }
-
- public void forEachRemaining(LongConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- long o = origin, b = bound;
- ThreadLocalRandom rng = ThreadLocalRandom.current();
- do {
- consumer.accept(rng.internalNextLong(o, b));
- } while (++i < f);
- }
- }
-
- }
-
- /**
- * Spliterator for double streams.
- */
- private static final class RandomDoublesSpliterator
- implements Spliterator.OfDouble {
- long index;
- final long fence;
- final double origin;
- final double bound;
- RandomDoublesSpliterator(long index, long fence,
- double origin, double bound) {
- this.index = index; this.fence = fence;
- this.origin = origin; this.bound = bound;
- }
-
- public RandomDoublesSpliterator trySplit() {
- long i = index, m = (i + fence) >>> 1;
- return (m <= i) ? null :
- new RandomDoublesSpliterator(i, index = m, origin, bound);
- }
-
- public long estimateSize() {
- return fence - index;
- }
-
- public int characteristics() {
- return (Spliterator.SIZED | Spliterator.SUBSIZED |
- Spliterator.NONNULL | Spliterator.IMMUTABLE);
- }
-
- public boolean tryAdvance(DoubleConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(ThreadLocalRandom.current().internalNextDouble(origin, bound));
- index = i + 1;
- return true;
- }
- return false;
- }
-
- public void forEachRemaining(DoubleConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- double o = origin, b = bound;
- ThreadLocalRandom rng = ThreadLocalRandom.current();
- do {
- consumer.accept(rng.internalNextDouble(o, b));
- } while (++i < f);
- }
- }
- }
-
-
// Within-package utilities
/*
@@ -1039,13 +345,6 @@
*/
private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
- /**
- * The least non-zero value returned by nextDouble(). This value
- * is scaled by a random value of 53 bits to produce a result.
- */
- private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
- private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24)
-
// IllegalArgumentException messages
static final String BAD_BOUND = "bound must be positive";
static final String BAD_RANGE = "bound must be greater than origin";
@@ -1066,10 +365,6 @@
private static final long INHERITEDACCESSCONTROLCONTEXT
= U.objectFieldOffset(Thread.class, "inheritedAccessControlContext");
- /** Rarely-used holder for the second of a pair of Gaussians */
- private static final ThreadLocal<Double> nextLocalGaussian =
- new ThreadLocal<>();
-
/** Generates per-thread initialization/probe field */
private static final AtomicInteger probeGenerator = new AtomicInteger();
@@ -1080,8 +375,8 @@
* The next seed for default constructors.
*/
private static final AtomicLong seeder
- = new AtomicLong(mix64(System.currentTimeMillis()) ^
- mix64(System.nanoTime()));
+ = new AtomicLong(RandomSupport.mixMurmur64(System.currentTimeMillis()) ^
+ RandomSupport.mixMurmur64(System.nanoTime()));
// at end of <clinit> to survive static initialization circularity
static {