ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.18
Committed: Fri Jul 19 19:34:43 2013 UTC (10 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.17: +1 -1 lines
Log Message:
enforce standard javadoc tag order

File Contents

# Content
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.io.ObjectStreamField;
10 import java.util.Random;
11 import java.util.concurrent.atomic.AtomicInteger;
12 import java.util.concurrent.atomic.AtomicLong;
13
14 /**
15 * A random number generator isolated to the current thread. Like the
16 * global {@link java.util.Random} generator used by the {@link
17 * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
18 * with an internally generated seed that may not otherwise be
19 * modified. When applicable, use of {@code ThreadLocalRandom} rather
20 * than shared {@code Random} objects in concurrent programs will
21 * typically encounter much less overhead and contention. Use of
22 * {@code ThreadLocalRandom} is particularly appropriate when multiple
23 * tasks (for example, each a {@link ForkJoinTask}) use random numbers
24 * in parallel in thread pools.
25 *
26 * <p>Usages of this class should typically be of the form:
27 * {@code ThreadLocalRandom.current().nextX(...)} (where
28 * {@code X} is {@code Int}, {@code Long}, etc).
29 * When all usages are of this form, it is never possible to
30 * accidently share a {@code ThreadLocalRandom} across multiple threads.
31 *
32 * <p>This class also provides additional commonly used bounded random
33 * generation methods.
34 *
35 * @since 1.7
36 * @author Doug Lea
37 */
38 public class ThreadLocalRandom extends Random {
39 /*
40 * This class implements the java.util.Random API (and subclasses
41 * Random) using a single static instance that accesses random
42 * number state held in class Thread (primarily, field
43 * threadLocalRandomSeed). In doing so, it also provides a home
44 * for managing package-private utilities that rely on exactly the
45 * same state as needed to maintain the ThreadLocalRandom
46 * instances. We leverage the need for an initialization flag
47 * field to also use it as a "probe" -- a self-adjusting thread
48 * hash used for contention avoidance, as well as a secondary
49 * simpler (xorShift) random seed that is conservatively used to
50 * avoid otherwise surprising users by hijacking the
51 * ThreadLocalRandom sequence. The dual use is a marriage of
52 * convenience, but is a simple and efficient way of reducing
53 * application-level overhead and footprint of most concurrent
54 * programs.
55 *
56 * Because this class is in a different package than class Thread,
57 * field access methods use Unsafe to bypass access control rules.
58 * The base functionality of Random methods is conveniently
59 * isolated in method next(bits), that just reads and writes the
60 * Thread field rather than its own field. However, to conform to
61 * the requirements of the Random superclass constructor, the
62 * common static ThreadLocalRandom maintains an "initialized"
63 * field for the sake of rejecting user calls to setSeed while
64 * still allowing a call from constructor. Note that
65 * serialization is completely unnecessary because there is only a
66 * static singleton. But we generate a serial form containing
67 * "rnd" and "initialized" fields to ensure compatibility across
68 * versions.
69 *
70 * Per-thread initialization is similar to that in the no-arg
71 * Random constructor, but we avoid correlation among not only
72 * initial seeds of those created in different threads, but also
73 * those created using class Random itself; while at the same time
74 * not changing any statistical properties. So we use the same
75 * underlying multiplicative sequence, but start the sequence far
76 * away from the base version, and then merge (xor) current time
77 * and per-thread probe bits to generate initial values.
78 *
79 * The nextLocalGaussian ThreadLocal supports the very rarely used
80 * nextGaussian method by providing a holder for the second of a
81 * pair of them. As is true for the base class version of this
82 * method, this time/space tradeoff is probably never worthwhile,
83 * but we provide identical statistical properties.
84 */
85
86 // same constants as Random, but must be redeclared because private
87 private static final long multiplier = 0x5DEECE66DL;
88 private static final long addend = 0xBL;
89 private static final long mask = (1L << 48) - 1;
90 private static final int PROBE_INCREMENT = 0x61c88647;
91
92 /** Generates the basis for per-thread initial seed values */
93 private static final AtomicLong seedGenerator =
94 new AtomicLong(1269533684904616924L);
95
96 /** Generates per-thread initialization/probe field */
97 private static final AtomicInteger probeGenerator =
98 new AtomicInteger(0xe80f8647);
99
100 /** Rarely-used holder for the second of a pair of Gaussians */
101 private static final ThreadLocal<Double> nextLocalGaussian =
102 new ThreadLocal<Double>();
103
104 /**
105 * Field used only during singleton initialization.
106 * True when constructor completes.
107 */
108 boolean initialized;
109
110 /** Constructor used only for static singleton */
111 private ThreadLocalRandom() {
112 initialized = true; // false during super() call
113 }
114
115 /** The common ThreadLocalRandom */
116 static final ThreadLocalRandom instance = new ThreadLocalRandom();
117
118 /**
119 * Initialize Thread fields for the current thread. Called only
120 * when Thread.threadLocalRandomProbe is zero, indicating that a
121 * thread local seed value needs to be generated. Note that even
122 * though the initialization is purely thread-local, we need to
123 * rely on (static) atomic generators to initialize the values.
124 */
125 static final void localInit() {
126 int p = probeGenerator.getAndAdd(PROBE_INCREMENT);
127 int probe = (p == 0) ? 1 : p; // skip 0
128 long current, next;
129 do { // same sequence as j.u.Random but different initial value
130 current = seedGenerator.get();
131 next = current * 181783497276652981L;
132 } while (!seedGenerator.compareAndSet(current, next));
133 long r = next ^ ((long)probe << 32) ^ System.nanoTime();
134 Thread t = Thread.currentThread();
135 UNSAFE.putLong(t, SEED, r);
136 UNSAFE.putInt(t, PROBE, probe);
137 }
138
139 /**
140 * Returns the current thread's {@code ThreadLocalRandom}.
141 *
142 * @return the current thread's {@code ThreadLocalRandom}
143 */
144 public static ThreadLocalRandom current() {
145 if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
146 localInit();
147 return instance;
148 }
149
150 /**
151 * Throws {@code UnsupportedOperationException}. Setting seeds in
152 * this generator is not supported.
153 *
154 * @throws UnsupportedOperationException always
155 */
156 public void setSeed(long seed) {
157 // only allow call from super() constructor
158 if (initialized)
159 throw new UnsupportedOperationException();
160 }
161
162 protected int next(int bits) {
163 Thread t; long r; // read and update per-thread seed
164 UNSAFE.putLong
165 (t = Thread.currentThread(), SEED,
166 r = (UNSAFE.getLong(t, SEED) * multiplier + addend) & mask);
167 return (int) (r >>> (48-bits));
168 }
169
170 /**
171 * Returns a pseudorandom, uniformly distributed value between the
172 * given least value (inclusive) and bound (exclusive).
173 *
174 * @param least the least value returned
175 * @param bound the upper bound (exclusive)
176 * @return the next value
177 * @throws IllegalArgumentException if least greater than or equal
178 * to bound
179 */
180 public int nextInt(int least, int bound) {
181 if (least >= bound)
182 throw new IllegalArgumentException();
183 return nextInt(bound - least) + least;
184 }
185
186 /**
187 * Returns a pseudorandom, uniformly distributed value
188 * between 0 (inclusive) and the specified value (exclusive).
189 *
190 * @param n the bound on the random number to be returned. Must be
191 * positive.
192 * @return the next value
193 * @throws IllegalArgumentException if n is not positive
194 */
195 public long nextLong(long n) {
196 if (n <= 0)
197 throw new IllegalArgumentException("n must be positive");
198 // Divide n by two until small enough for nextInt. On each
199 // iteration (at most 31 of them but usually much less),
200 // randomly choose both whether to include high bit in result
201 // (offset) and whether to continue with the lower vs upper
202 // half (which makes a difference only if odd).
203 long offset = 0;
204 while (n >= Integer.MAX_VALUE) {
205 int bits = next(2);
206 long half = n >>> 1;
207 long nextn = ((bits & 2) == 0) ? half : n - half;
208 if ((bits & 1) == 0)
209 offset += n - nextn;
210 n = nextn;
211 }
212 return offset + nextInt((int) n);
213 }
214
215 /**
216 * Returns a pseudorandom, uniformly distributed value between the
217 * given least value (inclusive) and bound (exclusive).
218 *
219 * @param least the least value returned
220 * @param bound the upper bound (exclusive)
221 * @return the next value
222 * @throws IllegalArgumentException if least greater than or equal
223 * to bound
224 */
225 public long nextLong(long least, long bound) {
226 if (least >= bound)
227 throw new IllegalArgumentException();
228 return nextLong(bound - least) + least;
229 }
230
231 /**
232 * Returns a pseudorandom, uniformly distributed {@code double} value
233 * between 0 (inclusive) and the specified value (exclusive).
234 *
235 * @param n the bound on the random number to be returned. Must be
236 * positive.
237 * @return the next value
238 * @throws IllegalArgumentException if n is not positive
239 */
240 public double nextDouble(double n) {
241 if (n <= 0)
242 throw new IllegalArgumentException("n must be positive");
243 return nextDouble() * n;
244 }
245
246 /**
247 * Returns a pseudorandom, uniformly distributed value between the
248 * given least value (inclusive) and bound (exclusive).
249 *
250 * @param least the least value returned
251 * @param bound the upper bound (exclusive)
252 * @return the next value
253 * @throws IllegalArgumentException if least greater than or equal
254 * to bound
255 */
256 public double nextDouble(double least, double bound) {
257 if (least >= bound)
258 throw new IllegalArgumentException();
259 return nextDouble() * (bound - least) + least;
260 }
261
262 public double nextGaussian() {
263 // Use nextLocalGaussian instead of nextGaussian field
264 Double d = nextLocalGaussian.get();
265 if (d != null) {
266 nextLocalGaussian.set(null);
267 return d.doubleValue();
268 }
269 double v1, v2, s;
270 do {
271 v1 = 2 * nextDouble() - 1; // between -1 and 1
272 v2 = 2 * nextDouble() - 1; // between -1 and 1
273 s = v1 * v1 + v2 * v2;
274 } while (s >= 1 || s == 0);
275 double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
276 nextLocalGaussian.set(new Double(v2 * multiplier));
277 return v1 * multiplier;
278 }
279
280 // Within-package utilities
281
282 /*
283 * Descriptions of the usages of the methods below can be found in
284 * the classes that use them. Briefly, a thread's "probe" value is
285 * a non-zero hash code that (probably) does not collide with
286 * other existing threads with respect to any power of two
287 * collision space. When it does collide, it is pseudo-randomly
288 * adjusted (using a Marsaglia XorShift). The nextSecondarySeed
289 * method is used in the same contexts as ThreadLocalRandom, but
290 * only for transient usages such as random adaptive spin/block
291 * sequences for which a cheap RNG suffices and for which it could
292 * in principle disrupt user-visible statistical properties of the
293 * main ThreadLocalRandom if we were to use it.
294 *
295 * Note: Because of package-protection issues, versions of some
296 * these methods also appear in some subpackage classes.
297 */
298
299 /**
300 * Returns the probe value for the current thread without forcing
301 * initialization. Note that invoking ThreadLocalRandom.current()
302 * can be used to force initialization on zero return.
303 */
304 static final int getProbe() {
305 return UNSAFE.getInt(Thread.currentThread(), PROBE);
306 }
307
308 /**
309 * Pseudo-randomly advances and records the given probe value for the
310 * given thread.
311 */
312 static final int advanceProbe(int probe) {
313 probe ^= probe << 13; // xorshift
314 probe ^= probe >>> 17;
315 probe ^= probe << 5;
316 UNSAFE.putInt(Thread.currentThread(), PROBE, probe);
317 return probe;
318 }
319
320 /**
321 * Returns the pseudo-randomly initialized or updated secondary seed.
322 */
323 static final int nextSecondarySeed() {
324 int r;
325 Thread t = Thread.currentThread();
326 if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
327 r ^= r << 13; // xorshift
328 r ^= r >>> 17;
329 r ^= r << 5;
330 }
331 else {
332 localInit();
333 if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
334 r = 1; // avoid zero
335 }
336 UNSAFE.putInt(t, SECONDARY, r);
337 return r;
338 }
339
340 // Serialization support
341
342 private static final long serialVersionUID = -5851777807851030925L;
343
344 /**
345 * @serialField rnd long
346 * seed for random computations
347 * @serialField initialized boolean
348 * always true
349 */
350 private static final ObjectStreamField[] serialPersistentFields = {
351 new ObjectStreamField("rnd", long.class),
352 new ObjectStreamField("initialized", boolean.class),
353 };
354
355 /**
356 * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
357 * @param s the stream
358 * @throws java.io.IOException if an I/O error occurs
359 */
360 private void writeObject(java.io.ObjectOutputStream s)
361 throws java.io.IOException {
362
363 java.io.ObjectOutputStream.PutField fields = s.putFields();
364 fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
365 fields.put("initialized", true);
366 s.writeFields();
367 }
368
369 /**
370 * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
371 * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
372 */
373 private Object readResolve() {
374 return current();
375 }
376
377 // Unsafe mechanics
378 private static final sun.misc.Unsafe UNSAFE;
379 private static final long SEED;
380 private static final long PROBE;
381 private static final long SECONDARY;
382 static {
383 try {
384 UNSAFE = sun.misc.Unsafe.getUnsafe();
385 Class<?> tk = Thread.class;
386 SEED = UNSAFE.objectFieldOffset
387 (tk.getDeclaredField("threadLocalRandomSeed"));
388 PROBE = UNSAFE.objectFieldOffset
389 (tk.getDeclaredField("threadLocalRandomProbe"));
390 SECONDARY = UNSAFE.objectFieldOffset
391 (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
392 } catch (Exception e) {
393 throw new Error(e);
394 }
395 }
396 }