/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file:
 *
 * 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/
 */

package java.util.concurrent;

import java.io.ObjectStreamField;
import java.security.AccessControlContext;
import java.util.Random;
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 jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;

A random number generator isolated to the current thread. Like the global Random generator used by the 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. Use of ThreadLocalRandom is particularly appropriate when multiple tasks (for example, each a ForkJoinTask) use random numbers in parallel in thread pools.

Usages of this class should typically be of the form: ThreadLocalRandom.current().nextX(...) (where X is Int, Long, etc). When all usages are of this form, it is never possible to accidentally share a ThreadLocalRandom across multiple threads.

This class also provides additional commonly used bounded random generation methods.

Instances of ThreadLocalRandom are not cryptographically secure. Consider instead using SecureRandom in security-sensitive applications. Additionally, default-constructed instances do not use a cryptographically random seed unless the system property java.util.secureRandomSeed is set to true.

Author:Doug Lea
Since:1.7
/** * 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. * * <p>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 * accidentally share a {@code ThreadLocalRandom} across multiple threads. * * <p>This class also provides additional commonly used bounded random * generation methods. * * <p>Instances of {@code ThreadLocalRandom} are not cryptographically * secure. Consider instead using {@link java.security.SecureRandom} * in security-sensitive applications. Additionally, * default-constructed instances do not use a cryptographically random * seed unless the {@linkplain System#getProperty system property} * {@code java.util.secureRandomSeed} is set to {@code true}. * * @since 1.7 * @author Doug Lea */
public class ThreadLocalRandom extends Random { /* * This class implements the java.util.Random API (and subclasses * Random) using a single static instance that accesses random * number state held in class Thread (primarily, field * threadLocalRandomSeed). In doing so, it also provides a home * for managing package-private utilities that rely on exactly the * same state as needed to maintain the ThreadLocalRandom * instances. We leverage the need for an initialization flag * field to also use it as a "probe" -- a self-adjusting thread * hash used for contention avoidance, as well as a secondary * simpler (xorShift) random seed that is conservatively used to * avoid otherwise surprising users by hijacking the * ThreadLocalRandom sequence. The dual use is a marriage of * convenience, but is a simple and efficient way of reducing * application-level overhead and footprint of most concurrent * programs. Even more opportunistically, we also define here * other package-private utilities that access Thread class * fields. * * Even though this class subclasses java.util.Random, it uses the * same basic algorithm as java.util.SplittableRandom. (See its * internal documentation for explanations, which are not repeated * here.) Because ThreadLocalRandoms are not splittable * though, we use only a single 64bit gamma. * * Because this class is in a different package than class Thread, * field access methods use Unsafe to bypass access control rules. * To conform to the requirements of the Random superclass * constructor, the common static ThreadLocalRandom maintains an * "initialized" field for the sake of rejecting user calls to * setSeed while still allowing a call from constructor. Note * that serialization is completely unnecessary because there is * only a static singleton. But we generate a serial form * containing "rnd" and "initialized" fields to ensure * compatibility across versions. * * Implementations of non-core methods are mostly the same as in * 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. */ 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); }
Field used only during singleton initialization. True when constructor completes.
/** * Field used only during singleton initialization. * True when constructor completes. */
boolean initialized;
Constructor used only for static singleton
/** Constructor used only for static singleton */
private ThreadLocalRandom() { initialized = true; // false during super() call }
Initialize Thread fields for the current thread. Called only when Thread.threadLocalRandomProbe is zero, indicating that a thread local seed value needs to be generated. Note that even though the initialization is purely thread-local, we need to rely on (static) atomic generators to initialize the values.
/** * Initialize Thread fields for the current thread. Called only * when Thread.threadLocalRandomProbe is zero, indicating that a * thread local seed value needs to be generated. Note that even * though the initialization is purely thread-local, we need to * rely on (static) atomic generators to initialize the values. */
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)); Thread t = Thread.currentThread(); U.putLong(t, SEED, seed); U.putInt(t, PROBE, probe); }
Returns the current thread's ThreadLocalRandom.
Returns:the current thread's ThreadLocalRandom
/** * Returns the current thread's {@code ThreadLocalRandom}. * * @return the current thread's {@code ThreadLocalRandom} */
public static ThreadLocalRandom current() { if (U.getInt(Thread.currentThread(), PROBE) == 0) localInit(); return instance; }
Throws UnsupportedOperationException. Setting seeds in this generator is not supported.
Throws:
/** * Throws {@code UnsupportedOperationException}. Setting seeds in * this generator is not supported. * * @throws UnsupportedOperationException always */
public void setSeed(long seed) { // only allow call from super() constructor if (initialized) throw new UnsupportedOperationException(); } final long nextSeed() { Thread t; long r; // read and update per-thread seed U.putLong(t = Thread.currentThread(), SEED, r = U.getLong(t, SEED) + GAMMA); return r; }
Generates a pseudorandom number with the indicated number of low-order bits. Because this class has no subclasses, this method cannot be invoked or overridden.
Params:
  • bits – random bits
Returns:the next pseudorandom value from this random number generator's sequence
/** * Generates a pseudorandom number with the indicated number of * low-order bits. Because this class has no subclasses, this * method cannot be invoked or overridden. * * @param bits random bits * @return the next pseudorandom value from this random number * generator's sequence */
protected int next(int bits) { return nextInt() >>> (32 - bits); }
The form of nextLong used by LongStream Spliterators. If origin is greater than bound, acts as unbounded form of nextLong, else as bounded form.
Params:
  • origin – the least value, unless greater than bound
  • bound – the upper bound (exclusive), must not equal origin
Returns:a pseudorandom value
/** * 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.
Params:
  • origin – the least value, unless greater than bound
  • bound – the upper bound (exclusive), must not equal origin
Returns:a pseudorandom value
/** * 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.
Params:
  • origin – the least value, unless greater than bound
  • bound – the upper bound (exclusive), must not equal origin
Returns:a pseudorandom value
/** * 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 int value.
Returns:a pseudorandom int value
/** * Returns a pseudorandom {@code int} value. * * @return a pseudorandom {@code int} value */
public int nextInt() { return mix32(nextSeed()); }
Returns a pseudorandom int value between zero (inclusive) and the specified bound (exclusive).
Params:
  • bound – the upper bound (exclusive). Must be positive.
Throws:
Returns:a pseudorandom int value between zero (inclusive) and the bound (exclusive)
/** * 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 int value between the specified origin (inclusive) and the specified bound (exclusive).
Params:
  • origin – the least value returned
  • bound – the upper bound (exclusive)
Throws:
Returns:a pseudorandom int value between the origin (inclusive) and the bound (exclusive)
/** * 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 long value.
Returns:a pseudorandom long value
/** * Returns a pseudorandom {@code long} value. * * @return a pseudorandom {@code long} value */
public long nextLong() { return mix64(nextSeed()); }
Returns a pseudorandom long value between zero (inclusive) and the specified bound (exclusive).
Params:
  • bound – the upper bound (exclusive). Must be positive.
Throws:
Returns:a pseudorandom long value between zero (inclusive) and the bound (exclusive)
/** * 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 long value between the specified origin (inclusive) and the specified bound (exclusive).
Params:
  • origin – the least value returned
  • bound – the upper bound (exclusive)
Throws:
Returns:a pseudorandom long value between the origin (inclusive) and the bound (exclusive)
/** * 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 double value between zero (inclusive) and one (exclusive).
Returns:a pseudorandom double value between zero (inclusive) and one (exclusive)
/** * 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 double value between 0.0 (inclusive) and the specified bound (exclusive).
Params:
  • bound – the upper bound (exclusive). Must be positive.
Throws:
Returns:a pseudorandom double value between zero (inclusive) and the bound (exclusive)
/** * 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 double value between the specified origin (inclusive) and bound (exclusive).
Params:
  • origin – the least value returned
  • bound – the upper bound (exclusive)
Throws:
Returns:a pseudorandom double value between the origin (inclusive) and the bound (exclusive)
/** * 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 boolean value.
Returns:a pseudorandom boolean value
/** * Returns a pseudorandom {@code boolean} value. * * @return a pseudorandom {@code boolean} value */
public boolean nextBoolean() { return mix32(nextSeed()) < 0; }
Returns a pseudorandom float value between zero (inclusive) and one (exclusive).
Returns:a pseudorandom float value between zero (inclusive) and one (exclusive)
/** * 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 streamSize number of pseudorandom int values.
Params:
  • streamSize – the number of values to generate
Throws:
Returns:a stream of pseudorandom int values
Since:1.8
/** * 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 int values.
Implementation Note:This method is implemented to be equivalent to ints(Long.MAX_VALUE).
Returns:a stream of pseudorandom int values
Since:1.8
/** * 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 streamSize number of pseudorandom int values, each conforming to the given origin (inclusive) and bound (exclusive).
Params:
  • streamSize – the number of values to generate
  • randomNumberOrigin – the origin (inclusive) of each random value
  • randomNumberBound – the bound (exclusive) of each random value
Throws:
  • IllegalArgumentException – if streamSize is less than zero, or randomNumberOrigin is greater than or equal to randomNumberBound
Returns:a stream of pseudorandom int values, each with the given origin (inclusive) and bound (exclusive)
Since:1.8
/** * 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 int values, each conforming to the given origin (inclusive) and bound (exclusive).
Params:
  • randomNumberOrigin – the origin (inclusive) of each random value
  • randomNumberBound – the bound (exclusive) of each random value
Throws:
Implementation Note:This method is implemented to be equivalent to ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound).
Returns:a stream of pseudorandom int values, each with the given origin (inclusive) and bound (exclusive)
Since:1.8
/** * 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 streamSize number of pseudorandom long values.
Params:
  • streamSize – the number of values to generate
Throws:
Returns:a stream of pseudorandom long values
Since:1.8
/** * 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 long values.
Implementation Note:This method is implemented to be equivalent to longs(Long.MAX_VALUE).
Returns:a stream of pseudorandom long values
Since:1.8
/** * 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 streamSize number of pseudorandom long, each conforming to the given origin (inclusive) and bound (exclusive).
Params:
  • streamSize – the number of values to generate
  • randomNumberOrigin – the origin (inclusive) of each random value
  • randomNumberBound – the bound (exclusive) of each random value
Throws:
  • IllegalArgumentException – if streamSize is less than zero, or randomNumberOrigin is greater than or equal to randomNumberBound
Returns:a stream of pseudorandom long values, each with the given origin (inclusive) and bound (exclusive)
Since:1.8
/** * 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); }
Returns an effectively unlimited stream of pseudorandom long values, each conforming to the given origin (inclusive) and bound (exclusive).
Params:
  • randomNumberOrigin – the origin (inclusive) of each random value
  • randomNumberBound – the bound (exclusive) of each random value
Throws:
Implementation Note:This method is implemented to be equivalent to longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound).
Returns:a stream of pseudorandom long values, each with the given origin (inclusive) and bound (exclusive)
Since:1.8
/** * 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 streamSize number of pseudorandom double values, each between zero (inclusive) and one (exclusive).
Params:
  • streamSize – the number of values to generate
Throws:
Returns:a stream of double values
Since:1.8
/** * 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 double values, each between zero (inclusive) and one (exclusive).
Implementation Note:This method is implemented to be equivalent to doubles(Long.MAX_VALUE).
Returns:a stream of pseudorandom double values
Since:1.8
/** * 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 streamSize number of pseudorandom double values, each conforming to the given origin (inclusive) and bound (exclusive).
Params:
  • streamSize – the number of values to generate
  • randomNumberOrigin – the origin (inclusive) of each random value
  • randomNumberBound – the bound (exclusive) of each random value
Throws:
  • IllegalArgumentException – if streamSize is less than zero, or randomNumberOrigin is greater than or equal to randomNumberBound
Returns:a stream of pseudorandom double values, each with the given origin (inclusive) and bound (exclusive)
Since:1.8
/** * 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 double values, each conforming to the given origin (inclusive) and bound (exclusive).
Params:
  • randomNumberOrigin – the origin (inclusive) of each random value
  • randomNumberBound – the bound (exclusive) of each random value
Throws:
Implementation Note:This method is implemented to be equivalent to doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound).
Returns:a stream of pseudorandom double values, each with the given origin (inclusive) and bound (exclusive)
Since:1.8
/** * 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.
/** * 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.
/** * 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.
/** * 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 /* * Descriptions of the usages of the methods below can be found in * the classes that use them. Briefly, a thread's "probe" value is * a non-zero hash code that (probably) does not collide with * other existing threads with respect to any power of two * collision space. When it does collide, it is pseudo-randomly * adjusted (using a Marsaglia XorShift). The nextSecondarySeed * method is used in the same contexts as ThreadLocalRandom, but * only for transient usages such as random adaptive spin/block * sequences for which a cheap RNG suffices and for which it could * in principle disrupt user-visible statistical properties of the * main ThreadLocalRandom if we were to use it. * * Note: Because of package-protection issues, versions of some * these methods also appear in some subpackage classes. */
Returns the probe value for the current thread without forcing initialization. Note that invoking ThreadLocalRandom.current() can be used to force initialization on zero return.
/** * Returns the probe value for the current thread without forcing * initialization. Note that invoking ThreadLocalRandom.current() * can be used to force initialization on zero return. */
static final int getProbe() { return U.getInt(Thread.currentThread(), PROBE); }
Pseudo-randomly advances and records the given probe value for the given thread.
/** * Pseudo-randomly advances and records the given probe value for the * given thread. */
static final int advanceProbe(int probe) { probe ^= probe << 13; // xorshift probe ^= probe >>> 17; probe ^= probe << 5; U.putInt(Thread.currentThread(), PROBE, probe); return probe; }
Returns the pseudo-randomly initialized or updated secondary seed.
/** * Returns the pseudo-randomly initialized or updated secondary seed. */
static final int nextSecondarySeed() { int r; Thread t = Thread.currentThread(); if ((r = U.getInt(t, SECONDARY)) != 0) { r ^= r << 13; // xorshift r ^= r >>> 17; r ^= r << 5; } else if ((r = mix32(seeder.getAndAdd(SEEDER_INCREMENT))) == 0) r = 1; // avoid zero U.putInt(t, SECONDARY, r); return r; } // Support for other package-private ThreadLocal access
Erases ThreadLocals by nulling out Thread maps.
/** * Erases ThreadLocals by nulling out Thread maps. */
static final void eraseThreadLocals(Thread thread) { U.putObject(thread, THREADLOCALS, null); U.putObject(thread, INHERITABLETHREADLOCALS, null); } static final void setInheritedAccessControlContext(Thread thread, AccessControlContext acc) { U.putObjectRelease(thread, INHERITEDACCESSCONTROLCONTEXT, acc); } // Serialization support private static final long serialVersionUID = -5851777807851030925L;
@serialFieldrnd long seed for random computations
@serialFieldinitialized boolean always true
/** * @serialField rnd long * seed for random computations * @serialField initialized boolean * always true */
private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("rnd", long.class), new ObjectStreamField("initialized", boolean.class), };
Saves the ThreadLocalRandom to a stream (that is, serializes it).
Params:
  • s – the stream
Throws:
/** * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it). * @param s the stream * @throws java.io.IOException if an I/O error occurs */
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { java.io.ObjectOutputStream.PutField fields = s.putFields(); fields.put("rnd", U.getLong(Thread.currentThread(), SEED)); fields.put("initialized", true); s.writeFields(); }
Returns the current thread's ThreadLocalRandom.
Returns:the current thread's ThreadLocalRandom
/** * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}. * @return the {@link #current() current} thread's {@code ThreadLocalRandom} */
private Object readResolve() { return current(); } // Static initialization
The seed increment.
/** * The seed increment. */
private static final long GAMMA = 0x9e3779b97f4a7c15L;
The increment for generating probe values.
/** * The increment for generating probe values. */
private static final int PROBE_INCREMENT = 0x9e3779b9;
The increment of seeder per new instance.
/** * The increment of seeder per new instance. */
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.
/** * 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"; static final String BAD_SIZE = "size must be non-negative"; // Unsafe mechanics private static final Unsafe U = Unsafe.getUnsafe(); private static final long SEED = U.objectFieldOffset (Thread.class, "threadLocalRandomSeed"); private static final long PROBE = U.objectFieldOffset (Thread.class, "threadLocalRandomProbe"); private static final long SECONDARY = U.objectFieldOffset (Thread.class, "threadLocalRandomSecondarySeed"); private static final long THREADLOCALS = U.objectFieldOffset (Thread.class, "threadLocals"); private static final long INHERITABLETHREADLOCALS = U.objectFieldOffset (Thread.class, "inheritableThreadLocals"); private static final long INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset (Thread.class, "inheritedAccessControlContext");
Rarely-used holder for the second of a pair of Gaussians
/** 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
/** Generates per-thread initialization/probe field */
private static final AtomicInteger probeGenerator = new AtomicInteger();
The common ThreadLocalRandom
/** The common ThreadLocalRandom */
static final ThreadLocalRandom instance = new ThreadLocalRandom();
The next seed for default constructors.
/** * The next seed for default constructors. */
private static final AtomicLong seeder = new AtomicLong(mix64(System.currentTimeMillis()) ^ mix64(System.nanoTime())); // at end of <clinit> to survive static initialization circularity static { String sec = VM.getSavedProperty("java.util.secureRandomSeed"); if (Boolean.parseBoolean(sec)) { byte[] seedBytes = java.security.SecureRandom.getSeed(8); long s = (long)seedBytes[0] & 0xffL; for (int i = 1; i < 8; ++i) s = (s << 8) | ((long)seedBytes[i] & 0xffL); seeder.set(s); } } }