--- jsr166/src/jsr166y/ThreadLocalRandom.java 2009/01/12 17:16:18 1.1
+++ jsr166/src/jsr166y/ThreadLocalRandom.java 2011/03/15 19:47:02 1.15
@@ -1,24 +1,36 @@
/*
* 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/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
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 {@code ThreadLocalRandom} is initialized
+ * with an internally generated seed that may not otherwise be
+ * modified. When applicable, use of {@code ThreadLocalRandom} rather
+ * than shared {@code Random} objects in concurrent programs will
+ * typically encounter much less overhead and contention. Use of
+ * {@code ThreadLocalRandom} is 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 a {@code ThreadLocalRandom} 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 +39,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.
+ * Initialization flag to permit calls to setSeed to succeed only
+ * while executing the Random constructor. We can't allow others
+ * since it would cause setting seed in one part of a program to
+ * unintentionally impact other usages by the thread.
*/
boolean initialized;
@@ -44,6 +56,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,37 +66,45 @@ public class ThreadLocalRandom extends R
}
};
- ThreadLocalRandom() { // construct only in localRandom.initialValue
- super(); // super constructor calls setSeed
+
+ /**
+ * Constructor called only by localRandom.initialValue.
+ */
+ ThreadLocalRandom() {
+ super();
+ initialized = true;
}
/**
- * Returns the current Thread's ThreadLocalRandom
- * @return the current Thread's ThreadLocalRandom
+ * Returns the current thread's {@code ThreadLocalRandom}.
+ *
+ * @return the current thread's {@code ThreadLocalRandom}
*/
public static ThreadLocalRandom current() {
return localRandom.get();
}
/**
- * Throws UnsupportedOperationException. Setting seeds in this
- * generator is unsupported.
- * @throw UnsupportedOperationException always
+ * Throws {@code UnsupportedOperationException}. Setting seeds in
+ * this generator is not supported.
+ *
+ * @throws UnsupportedOperationException always
*/
- public void setSeed(long seed) {
+ public void setSeed(long seed) {
if (initialized)
throw new UnsupportedOperationException();
- initialized = true;
rnd = (seed ^ multiplier) & mask;
}
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 +119,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 +129,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 +164,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 +180,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 +193,5 @@ public class ThreadLocalRandom extends R
return nextDouble() * (bound - least) + least;
}
-}
\ No newline at end of file
+ private static final long serialVersionUID = -5851777807851030925L;
+}