--- jsr166/src/jsr166y/ThreadLocalRandom.java 2009/01/12 17:16:18 1.1
+++ jsr166/src/jsr166y/ThreadLocalRandom.java 2009/07/31 16:25:20 1.11
@@ -5,20 +5,31 @@
*/
package jsr166y;
-import java.util.*;
+
+import java.util.Random;
/**
- * A Random number generator with the same properties as {@link
- * Random} but isolated to the current Thread. Like the global
- * generator used by {@link java.lang.Math}, a ThreadLocalRandom is
- * initialized with an internally generated seed that may not
- * otherwise be modified. When applicable, use of ThreadLocalRandom
- * rather than shared Random objects in concurrent programs will
- * typically encounter less overhead and contention. The most common
- * usage form is: ThreadLocalRandom.current().nextX()
.
+ * A random number generator isolated to the current Thread. Like the
+ * global {@link java.util.Random} generator used by the {@link
+ * java.lang.Math} class, a ThreadLocalRandom is initialized with an
+ * internally generated seed that may not otherwise be modified. When
+ * applicable, use of ThreadLocalRandom rather than shared Random
+ * objects in concurrent programs will typically encounter much less
+ * overhead and contention. ThreadLocalRandoms are particularly
+ * appropriate when multiple tasks (for example, each a {@link
+ * ForkJoinTask}), use random numbers in parallel in thread pools.
+ *
+ *
Usages of this class should typically be of the form:
+ * {@code ThreadLocalRandom.current().nextX(...)} (where
+ * {@code X} is {@code Int}, {@code Long}, etc).
+ * When all usages are of this form, it is never possible to
+ * accidently share ThreadLocalRandoms across multiple threads.
*
*
This class also provides additional commonly used bounded random
* generation methods.
+ *
+ * @since 1.7
+ * @author Doug Lea
*/
public class ThreadLocalRandom extends Random {
// same constants as Random, but must be redeclared because private
@@ -27,15 +38,15 @@ public class ThreadLocalRandom extends R
private final static long mask = (1L << 48) - 1;
/**
- * The random seed. We can't use super.seed
+ * The random seed. We can't use super.seed.
*/
- private long rnd;
+ private long rnd;
/**
* Initialization flag to permit the first and only allowed call
* to setSeed (inside Random constructor) to succeed. We can't
* allow others since it would cause setting seed in one part of a
- * program to inintentionally impact other usages by the thread.
+ * program to unintentionally impact other usages by the thread.
*/
boolean initialized;
@@ -44,6 +55,9 @@ public class ThreadLocalRandom extends R
// each other.
private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
+ /**
+ * The actual ThreadLocal
+ */
private static final ThreadLocal localRandom =
new ThreadLocal() {
protected ThreadLocalRandom initialValue() {
@@ -51,12 +65,19 @@ public class ThreadLocalRandom extends R
}
};
- ThreadLocalRandom() { // construct only in localRandom.initialValue
- super(); // super constructor calls setSeed
+
+ /**
+ * Constructor called only by localRandom.initialValue.
+ * We rely on the fact that the superclass no-arg constructor
+ * invokes setSeed exactly once to initialize.
+ */
+ ThreadLocalRandom() {
+ super();
}
/**
- * Returns the current Thread's ThreadLocalRandom
+ * Returns the current Thread's ThreadLocalRandom.
+ *
* @return the current Thread's ThreadLocalRandom
*/
public static ThreadLocalRandom current() {
@@ -66,9 +87,10 @@ public class ThreadLocalRandom extends R
/**
* Throws UnsupportedOperationException. Setting seeds in this
* generator is unsupported.
- * @throw UnsupportedOperationException always
+ *
+ * @throws UnsupportedOperationException always
*/
- public void setSeed(long seed) {
+ public void setSeed(long seed) {
if (initialized)
throw new UnsupportedOperationException();
initialized = true;
@@ -76,12 +98,14 @@ public class ThreadLocalRandom extends R
}
protected int next(int bits) {
- return (int)((rnd = (rnd * multiplier + addend) & mask) >>> (48-bits));
+ rnd = (rnd * multiplier + addend) & mask;
+ return (int) (rnd >>> (48-bits));
}
/**
* Returns a pseudorandom, uniformly distributed value between the
* given least value (inclusive) and bound (exclusive).
+ *
* @param least the least value returned
* @param bound the upper bound (exclusive)
* @throws IllegalArgumentException if least greater than or equal
@@ -96,7 +120,8 @@ public class ThreadLocalRandom extends R
/**
* Returns a pseudorandom, uniformly distributed value
- * between 0 (inclusive) and the specified value (exclusive)
+ * between 0 (inclusive) and the specified value (exclusive).
+ *
* @param n the bound on the random number to be returned. Must be
* positive.
* @return the next value
@@ -105,21 +130,27 @@ public class ThreadLocalRandom extends R
public long nextLong(long n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
+ // Divide n by two until small enough for nextInt. On each
+ // iteration (at most 31 of them but usually much less),
+ // randomly choose both whether to include high bit in result
+ // (offset) and whether to continue with the lower vs upper
+ // half (which makes a difference only if odd).
long offset = 0;
- while (n >= Integer.MAX_VALUE) { // randomly pick half range
- int bits = next(2); // 2nd bit for odd vs even split
+ while (n >= Integer.MAX_VALUE) {
+ int bits = next(2);
long half = n >>> 1;
- long nextn = ((bits & 2) == 0)? half : n - half;
+ long nextn = ((bits & 2) == 0) ? half : n - half;
if ((bits & 1) == 0)
offset += n - nextn;
n = nextn;
}
- return offset + nextInt((int)n);
+ return offset + nextInt((int) n);
}
/**
* Returns a pseudorandom, uniformly distributed value between the
* given least value (inclusive) and bound (exclusive).
+ *
* @param least the least value returned
* @param bound the upper bound (exclusive)
* @return the next value
@@ -134,7 +165,8 @@ public class ThreadLocalRandom extends R
/**
* Returns a pseudorandom, uniformly distributed {@code double} value
- * between 0 (inclusive) and the specified value (exclusive)
+ * between 0 (inclusive) and the specified value (exclusive).
+ *
* @param n the bound on the random number to be returned. Must be
* positive.
* @return the next value
@@ -149,6 +181,7 @@ public class ThreadLocalRandom extends R
/**
* Returns a pseudorandom, uniformly distributed value between the
* given least value (inclusive) and bound (exclusive).
+ *
* @param least the least value returned
* @param bound the upper bound (exclusive)
* @return the next value
@@ -161,4 +194,5 @@ public class ThreadLocalRandom extends R
return nextDouble() * (bound - least) + least;
}
-}
\ No newline at end of file
+ private static final long serialVersionUID = -5851777807851030925L;
+}