--- jsr166/src/main/java/util/SplittableRandom.java 2014/12/31 07:54:13 1.26
+++ jsr166/src/main/java/util/SplittableRandom.java 2016/12/20 22:08:05 1.38
@@ -52,15 +52,15 @@ import java.util.stream.StreamSupport;
* types and ranges, but similar properties are expected to hold, at
* least approximately, for others as well. The period
* (length of any series of generated values before it repeats) is at
- * least 264.
+ * least 264.
*
- *
Method {@link #split} constructs and returns a new
+ * Method {@link #split} constructs and returns a new
* SplittableRandom instance that shares no mutable state with the
* current instance. However, with very high probability, the
* values collectively generated by the two objects have the same
* statistical properties as if the same quantity of values were
* generated by a single thread using a single {@code
- * SplittableRandom} object.
+ * SplittableRandom} object.
*
* Instances of SplittableRandom are not thread-safe.
* They are designed to be split, not shared, across threads. For
@@ -71,7 +71,7 @@ import java.util.stream.StreamSupport;
*
* This class provides additional methods for generating random
* streams, that employ the above techniques when used in {@code
- * stream.parallel()} mode.
+ * stream.parallel()} mode.
*
*
*
@@ -219,31 +219,33 @@ public final class SplittableRandom {
return seed += gamma;
}
+ // IllegalArgumentException messages
+ static final String BAD_BOUND = "bound must be positive";
+ static final String BAD_RANGE = "bound must be greater than origin";
+ static final String BAD_SIZE = "size must be non-negative";
+
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(initialSeed());
-
- private static long initialSeed() {
- String pp = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction(
- "java.util.secureRandomSeed"));
- if (pp != null && pp.equalsIgnoreCase("true")) {
+ private static final AtomicLong defaultGen
+ = new AtomicLong(mix64(System.currentTimeMillis()) ^
+ mix64(System.nanoTime()));
+
+ // at end of to survive static initialization circularity
+ static {
+ if (java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction() {
+ public Boolean run() {
+ return Boolean.getBoolean("java.util.secureRandomSeed");
+ }})) {
byte[] seedBytes = java.security.SecureRandom.getSeed(8);
- long s = (long)(seedBytes[0]) & 0xffL;
+ long s = (long)seedBytes[0] & 0xffL;
for (int i = 1; i < 8; ++i)
- s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
- return s;
+ s = (s << 8) | ((long)seedBytes[i] & 0xffL);
+ defaultGen.set(s);
}
- return (mix64(System.currentTimeMillis()) ^
- mix64(System.nanoTime()));
}
- // IllegalArgumentException messages
- static final String BadBound = "bound must be positive";
- static final String BadRange = "bound must be greater than origin";
- static final String BadSize = "size must be non-negative";
-
/*
* Internal versions of nextX methods used by streams, as well as
* the public nextX(origin, bound) methods. These exist mainly to
@@ -373,7 +375,7 @@ public final class SplittableRandom {
* may, and typically does, vary across program invocations.
*/
public SplittableRandom() { // emulate defaultGen.split()
- long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
+ long s = defaultGen.getAndAdd(GOLDEN_GAMMA << 1);
this.seed = mix64(s);
this.gamma = mixGamma(s + GOLDEN_GAMMA);
}
@@ -416,7 +418,7 @@ public final class SplittableRandom {
*/
public int nextInt(int bound) {
if (bound <= 0)
- throw new IllegalArgumentException(BadBound);
+ throw new IllegalArgumentException(BAD_BOUND);
// Specialize internalNextInt for origin 0
int r = mix32(nextSeed());
int m = bound - 1;
@@ -444,7 +446,7 @@ public final class SplittableRandom {
*/
public int nextInt(int origin, int bound) {
if (origin >= bound)
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return internalNextInt(origin, bound);
}
@@ -468,7 +470,7 @@ public final class SplittableRandom {
*/
public long nextLong(long bound) {
if (bound <= 0)
- throw new IllegalArgumentException(BadBound);
+ throw new IllegalArgumentException(BAD_BOUND);
// Specialize internalNextLong for origin 0
long r = mix64(nextSeed());
long m = bound - 1;
@@ -496,7 +498,7 @@ public final class SplittableRandom {
*/
public long nextLong(long origin, long bound) {
if (origin >= bound)
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return internalNextLong(origin, bound);
}
@@ -522,7 +524,7 @@ public final class SplittableRandom {
*/
public double nextDouble(double bound) {
if (!(bound > 0.0))
- throw new IllegalArgumentException(BadBound);
+ 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);
@@ -541,7 +543,7 @@ public final class SplittableRandom {
*/
public double nextDouble(double origin, double bound) {
if (!(origin < bound))
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return internalNextDouble(origin, bound);
}
@@ -569,7 +571,7 @@ public final class SplittableRandom {
*/
public IntStream ints(long streamSize) {
if (streamSize < 0L)
- throw new IllegalArgumentException(BadSize);
+ throw new IllegalArgumentException(BAD_SIZE);
return StreamSupport.intStream
(new RandomIntsSpliterator
(this, 0L, streamSize, Integer.MAX_VALUE, 0),
@@ -610,9 +612,9 @@ public final class SplittableRandom {
public IntStream ints(long streamSize, int randomNumberOrigin,
int randomNumberBound) {
if (streamSize < 0L)
- throw new IllegalArgumentException(BadSize);
+ throw new IllegalArgumentException(BAD_SIZE);
if (randomNumberOrigin >= randomNumberBound)
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return StreamSupport.intStream
(new RandomIntsSpliterator
(this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
@@ -636,7 +638,7 @@ public final class SplittableRandom {
*/
public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
if (randomNumberOrigin >= randomNumberBound)
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return StreamSupport.intStream
(new RandomIntsSpliterator
(this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
@@ -655,7 +657,7 @@ public final class SplittableRandom {
*/
public LongStream longs(long streamSize) {
if (streamSize < 0L)
- throw new IllegalArgumentException(BadSize);
+ throw new IllegalArgumentException(BAD_SIZE);
return StreamSupport.longStream
(new RandomLongsSpliterator
(this, 0L, streamSize, Long.MAX_VALUE, 0L),
@@ -696,9 +698,9 @@ public final class SplittableRandom {
public LongStream longs(long streamSize, long randomNumberOrigin,
long randomNumberBound) {
if (streamSize < 0L)
- throw new IllegalArgumentException(BadSize);
+ throw new IllegalArgumentException(BAD_SIZE);
if (randomNumberOrigin >= randomNumberBound)
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return StreamSupport.longStream
(new RandomLongsSpliterator
(this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
@@ -722,7 +724,7 @@ public final class SplittableRandom {
*/
public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
if (randomNumberOrigin >= randomNumberBound)
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return StreamSupport.longStream
(new RandomLongsSpliterator
(this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
@@ -741,7 +743,7 @@ public final class SplittableRandom {
*/
public DoubleStream doubles(long streamSize) {
if (streamSize < 0L)
- throw new IllegalArgumentException(BadSize);
+ throw new IllegalArgumentException(BAD_SIZE);
return StreamSupport.doubleStream
(new RandomDoublesSpliterator
(this, 0L, streamSize, Double.MAX_VALUE, 0.0),
@@ -784,9 +786,9 @@ public final class SplittableRandom {
public DoubleStream doubles(long streamSize, double randomNumberOrigin,
double randomNumberBound) {
if (streamSize < 0L)
- throw new IllegalArgumentException(BadSize);
+ throw new IllegalArgumentException(BAD_SIZE);
if (!(randomNumberOrigin < randomNumberBound))
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return StreamSupport.doubleStream
(new RandomDoublesSpliterator
(this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
@@ -810,7 +812,7 @@ public final class SplittableRandom {
*/
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
if (!(randomNumberOrigin < randomNumberBound))
- throw new IllegalArgumentException(BadRange);
+ throw new IllegalArgumentException(BAD_RANGE);
return StreamSupport.doubleStream
(new RandomDoublesSpliterator
(this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
@@ -825,7 +827,8 @@ public final class SplittableRandom {
* approach. The long and double versions of this class are
* identical except for types.
*/
- static final class RandomIntsSpliterator implements Spliterator.OfInt {
+ private static final class RandomIntsSpliterator
+ implements Spliterator.OfInt {
final SplittableRandom rng;
long index;
final long fence;
@@ -880,7 +883,8 @@ public final class SplittableRandom {
/**
* Spliterator for long streams.
*/
- static final class RandomLongsSpliterator implements Spliterator.OfLong {
+ private static final class RandomLongsSpliterator
+ implements Spliterator.OfLong {
final SplittableRandom rng;
long index;
final long fence;
@@ -936,7 +940,8 @@ public final class SplittableRandom {
/**
* Spliterator for double streams.
*/
- static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
+ private static final class RandomDoublesSpliterator
+ implements Spliterator.OfDouble {
final SplittableRandom rng;
long index;
final long fence;