1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  */
6 
7 package java.util.concurrent;
8 
9 import java.util.Random;
10 
11 /**
12  * A random number generator isolated to the current thread.  Like the
13  * global {@link java.util.Random} generator used by the {@link
14  * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
15  * with an internally generated seed that may not otherwise be
16  * modified. When applicable, use of {@code ThreadLocalRandom} rather
17  * than shared {@code Random} objects in concurrent programs will
18  * typically encounter much less overhead and contention.  Use of
19  * {@code ThreadLocalRandom} is particularly appropriate when multiple
20  * tasks (for example, each a {@link ForkJoinTask}) use random numbers
21  * in parallel in thread pools.
22  *
23  * <p>Usages of this class should typically be of the form:
24  * {@code ThreadLocalRandom.current().nextX(...)} (where
25  * {@code X} is {@code Int}, {@code Long}, etc).
26  * When all usages are of this form, it is never possible to
27  * accidently share a {@code ThreadLocalRandom} across multiple threads.
28  *
29  * <p>This class also provides additional commonly used bounded random
30  * generation methods.
31  *
32  * @since 1.7
33  * @author Doug Lea
34  */
35 public class ThreadLocalRandom extends Random {
36     // same constants as Random, but must be redeclared because private
37     private static final long multiplier = 0x5DEECE66DL;
38     private static final long addend = 0xBL;
39     private static final long mask = (1L << 48) - 1;
40 
41     /**
42      * The random seed. We can't use super.seed.
43      */
44     private long rnd;
45 
46     /**
47      * Initialization flag to permit calls to setSeed to succeed only
48      * while executing the Random constructor.  We can't allow others
49      * since it would cause setting seed in one part of a program to
50      * unintentionally impact other usages by the thread.
51      */
52     boolean initialized;
53 
54     // Padding to help avoid memory contention among seed updates in
55     // different TLRs in the common case that they are located near
56     // each other.
57     private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
58 
59     /**
60      * The actual ThreadLocal
61      */
62     private static final ThreadLocal<ThreadLocalRandom> localRandom =
63         new ThreadLocal<ThreadLocalRandom>() {
64             protected ThreadLocalRandom initialValue() {
65                 return new ThreadLocalRandom();
66             }
67     };
68 
69 
70     /**
71      * Constructor called only by localRandom.initialValue.
72      */
ThreadLocalRandom()73     ThreadLocalRandom() {
74         super();
75         initialized = true;
76     }
77 
78     /**
79      * Returns the current thread's {@code ThreadLocalRandom}.
80      *
81      * @return the current thread's {@code ThreadLocalRandom}
82      */
current()83     public static ThreadLocalRandom current() {
84         return localRandom.get();
85     }
86 
87     /**
88      * Throws {@code UnsupportedOperationException}.  Setting seeds in
89      * this generator is not supported.
90      *
91      * @throws UnsupportedOperationException always
92      */
setSeed(long seed)93     public void setSeed(long seed) {
94         if (initialized)
95             throw new UnsupportedOperationException();
96         rnd = (seed ^ multiplier) & mask;
97     }
98 
next(int bits)99     protected int next(int bits) {
100         rnd = (rnd * multiplier + addend) & mask;
101         return (int) (rnd >>> (48-bits));
102     }
103 
104     /**
105      * Returns a pseudorandom, uniformly distributed value between the
106      * given least value (inclusive) and bound (exclusive).
107      *
108      * @param least the least value returned
109      * @param bound the upper bound (exclusive)
110      * @throws IllegalArgumentException if least greater than or equal
111      * to bound
112      * @return the next value
113      */
nextInt(int least, int bound)114     public int nextInt(int least, int bound) {
115         if (least >= bound)
116             throw new IllegalArgumentException();
117         return nextInt(bound - least) + least;
118     }
119 
120     /**
121      * Returns a pseudorandom, uniformly distributed value
122      * between 0 (inclusive) and the specified value (exclusive).
123      *
124      * @param n the bound on the random number to be returned.  Must be
125      *        positive.
126      * @return the next value
127      * @throws IllegalArgumentException if n is not positive
128      */
nextLong(long n)129     public long nextLong(long n) {
130         if (n <= 0)
131             throw new IllegalArgumentException("n must be positive");
132         // Divide n by two until small enough for nextInt. On each
133         // iteration (at most 31 of them but usually much less),
134         // randomly choose both whether to include high bit in result
135         // (offset) and whether to continue with the lower vs upper
136         // half (which makes a difference only if odd).
137         long offset = 0;
138         while (n >= Integer.MAX_VALUE) {
139             int bits = next(2);
140             long half = n >>> 1;
141             long nextn = ((bits & 2) == 0) ? half : n - half;
142             if ((bits & 1) == 0)
143                 offset += n - nextn;
144             n = nextn;
145         }
146         return offset + nextInt((int) n);
147     }
148 
149     /**
150      * Returns a pseudorandom, uniformly distributed value between the
151      * given least value (inclusive) and bound (exclusive).
152      *
153      * @param least the least value returned
154      * @param bound the upper bound (exclusive)
155      * @return the next value
156      * @throws IllegalArgumentException if least greater than or equal
157      * to bound
158      */
nextLong(long least, long bound)159     public long nextLong(long least, long bound) {
160         if (least >= bound)
161             throw new IllegalArgumentException();
162         return nextLong(bound - least) + least;
163     }
164 
165     /**
166      * Returns a pseudorandom, uniformly distributed {@code double} value
167      * between 0 (inclusive) and the specified value (exclusive).
168      *
169      * @param n the bound on the random number to be returned.  Must be
170      *        positive.
171      * @return the next value
172      * @throws IllegalArgumentException if n is not positive
173      */
nextDouble(double n)174     public double nextDouble(double n) {
175         if (n <= 0)
176             throw new IllegalArgumentException("n must be positive");
177         return nextDouble() * n;
178     }
179 
180     /**
181      * Returns a pseudorandom, uniformly distributed value between the
182      * given least value (inclusive) and bound (exclusive).
183      *
184      * @param least the least value returned
185      * @param bound the upper bound (exclusive)
186      * @return the next value
187      * @throws IllegalArgumentException if least greater than or equal
188      * to bound
189      */
nextDouble(double least, double bound)190     public double nextDouble(double least, double bound) {
191         if (least >= bound)
192             throw new IllegalArgumentException();
193         return nextDouble() * (bound - least) + least;
194     }
195 
196     private static final long serialVersionUID = -5851777807851030925L;
197 }
198