ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.65
Committed: Fri Mar 25 14:31:27 2022 UTC (2 years, 2 months ago) by dl
Branch: MAIN
Changes since 1.64: +1 -1 lines
Log Message:
Mark ThreadLocalRandom final because it is not subclassable

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 * Additional modifications by Guy Steele in 2019 to refactor the code
6 * and to implement the {@link RandomGenerator} interface.
7 */
8
9 package java.util.concurrent;
10
11 import java.io.ObjectStreamField;
12 import java.math.BigInteger;
13 import java.security.AccessControlContext;
14 import java.util.Map;
15 import java.util.Random;
16 import java.util.Spliterator;
17 import java.util.concurrent.atomic.AtomicInteger;
18 import java.util.concurrent.atomic.AtomicLong;
19 import java.util.random.RandomGenerator;
20 import java.util.stream.DoubleStream;
21 import java.util.stream.IntStream;
22 import java.util.stream.LongStream;
23 import jdk.internal.util.random.RandomSupport;
24 import jdk.internal.util.random.RandomSupport.*;
25 import jdk.internal.misc.Unsafe;
26 import jdk.internal.misc.VM;
27
28 /**
29 * A random number generator (with period 2<sup>64</sup>) isolated
30 * to the current thread. Like the global {@link java.util.Random}
31 * generator used by the {@link java.lang.Math} class,
32 * a {@code ThreadLocalRandom} is initialized
33 * with an internally generated seed that may not otherwise be
34 * modified. When applicable, use of {@code ThreadLocalRandom} rather
35 * than shared {@code Random} objects in concurrent programs will
36 * typically encounter much less overhead and contention. Use of
37 * {@code ThreadLocalRandom} is particularly appropriate when multiple
38 * tasks (for example, each a {@link ForkJoinTask}) use random numbers
39 * in parallel in thread pools.
40 *
41 * <p>Usages of this class should typically be of the form:
42 * {@code ThreadLocalRandom.current().nextX(...)} (where
43 * {@code X} is {@code Int}, {@code Long}, etc).
44 * When all usages are of this form, it is never possible to
45 * accidentally share a {@code ThreadLocalRandom} across multiple threads.
46 *
47 * <p>This class also provides additional commonly used bounded random
48 * generation methods.
49 *
50 * <p>Instances of {@code ThreadLocalRandom} are not cryptographically
51 * secure. Consider instead using {@link java.security.SecureRandom}
52 * in security-sensitive applications. Additionally,
53 * default-constructed instances do not use a cryptographically random
54 * seed unless the {@linkplain System#getProperty system property}
55 * {@code java.util.secureRandomSeed} is set to {@code true}.
56 *
57 * @since 1.7
58 * @author Doug Lea
59 */
60
61 @RandomGeneratorProperties(
62 name = "ThreadLocalRandom",
63 i = 64, j = 0, k = 0,
64 equidistribution = 1
65 )
66 public final class ThreadLocalRandom extends Random {
67 /*
68 * This class implements the java.util.Random API (and subclasses
69 * Random) using a single static instance that accesses 64 bits of
70 * random number state held in class java.lang.Thread (field
71 * threadLocalRandomSeed). In doing so, it also provides a home
72 * for managing package-private utilities that rely on exactly the
73 * same state as needed to maintain the ThreadLocalRandom
74 * instances. We leverage the need for an initialization flag
75 * field to also use it as a "probe" -- a self-adjusting thread
76 * hash used for contention avoidance, as well as a secondary
77 * simpler (xorShift) random seed that is conservatively used to
78 * avoid otherwise surprising users by hijacking the
79 * ThreadLocalRandom sequence. The dual use is a marriage of
80 * convenience, but is a simple and efficient way of reducing
81 * application-level overhead and footprint of most concurrent
82 * programs. Even more opportunistically, we also define here
83 * other package-private utilities that access Thread class
84 * fields.
85 *
86 * Even though this class subclasses java.util.Random, it uses the
87 * same basic algorithm as java.util.SplittableRandom. (See its
88 * internal documentation for explanations, which are not repeated
89 * here.) Note that ThreadLocalRandom is not a "splittable" generator
90 * (it does not support the split method), but it behaves as if
91 * one instance of the SplittableRandom algorithm had been
92 * created for each thread, each with a distinct gamma parameter
93 * (calculated from the thread id).
94 *
95 * Because this class is in a different package than class Thread,
96 * field access methods use Unsafe to bypass access control rules.
97 * To conform to the requirements of the Random superclass
98 * constructor, the common static ThreadLocalRandom maintains an
99 * "initialized" field for the sake of rejecting user calls to
100 * setSeed while still allowing a call from constructor. Note
101 * that serialization is completely unnecessary because there is
102 * only a static singleton. But we generate a serial form
103 * containing "rnd" and "initialized" fields to ensure
104 * compatibility across versions.
105 *
106 * Implementations of non-core methods are mostly the same as in
107 * SplittableRandom, that were in part derived from a previous
108 * version of this class.
109 *
110 * This implementation of ThreadLocalRandom overrides the
111 * definition of the nextGaussian() method in the class Random,
112 * and instead uses the ziggurat-based algorithm that is the
113 * default for the RandomGenerator interface.
114 */
115
116 private static int mix32(long z) {
117 z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
118 return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
119 }
120
121 /**
122 * Field used only during singleton initialization.
123 * True when constructor completes.
124 */
125 boolean initialized;
126
127 /** Constructor used only for static singleton */
128 private ThreadLocalRandom() {
129 initialized = true; // false during super() call
130 }
131
132 /**
133 * Initialize Thread fields for the current thread. Called only
134 * when Thread.threadLocalRandomProbe is zero, indicating that a
135 * thread local seed value needs to be generated. Note that even
136 * though the initialization is purely thread-local, we need to
137 * rely on (static) atomic generators to initialize the values.
138 */
139 static final void localInit() {
140 int p = probeGenerator.addAndGet(PROBE_INCREMENT);
141 int probe = (p == 0) ? 1 : p; // skip 0
142 long seed = RandomSupport.mixMurmur64(seeder.getAndAdd(SEEDER_INCREMENT));
143 Thread t = Thread.currentThread();
144 U.putLong(t, SEED, seed);
145 U.putInt(t, PROBE, probe);
146 }
147
148 /**
149 * Returns the current thread's {@code ThreadLocalRandom} object.
150 * Methods of this object should be called only by the current thread,
151 * not by other threads.
152 *
153 * @return the current thread's {@code ThreadLocalRandom}
154 */
155 public static ThreadLocalRandom current() {
156 if (U.getInt(Thread.currentThread(), PROBE) == 0)
157 localInit();
158 return instance;
159 }
160
161 /**
162 * Throws {@code UnsupportedOperationException}. Setting seeds in
163 * this generator is not supported.
164 *
165 * @throws UnsupportedOperationException always
166 */
167 public void setSeed(long seed) {
168 // only allow call from super() constructor
169 if (initialized)
170 throw new UnsupportedOperationException();
171 }
172
173 /**
174 * Update the thread local seed value by adding to it the sum
175 * of {@code GOLDEN_GAMMA} (an odd value) and twice the thread id.
176 * This sum is always odd (to guarantee that the generator
177 * has maximum period) and is different for different threads.
178 * Because thread id values are allocated consecutively starting
179 * from 0, the high 32 bits of this sum will be the same as the
180 * high 32 bits of {@code GOLDEN_GAMMA} unless an extremely large
181 * number of threads have been created, and so the overall
182 * value added to the thread local seed value will have at least
183 * fourteen 01 and 10 transitions (see the documentation for the
184 * method {@code mixGamma} in class {@code SplittableRandom}),
185 * which should provide adequate statistical quality for
186 * applications likely to use {@code ThreadLocalRandom}.
187 */
188 final long nextSeed() {
189 Thread t; long r; // read and update per-thread seed
190 U.putLong(t = Thread.currentThread(), SEED,
191 r = U.getLong(t, SEED) + (t.getId() << 1) + GOLDEN_GAMMA);
192 return r;
193 }
194
195 /**
196 * Generates a pseudorandom number with the indicated number of
197 * low-order bits. Because this class has no subclasses, this
198 * method cannot be invoked or overridden.
199 *
200 * @param bits random bits
201 * @return the next pseudorandom value from this random number
202 * generator's sequence
203 */
204 protected int next(int bits) {
205 return nextInt() >>> (32 - bits);
206 }
207
208 // Within-package utilities
209
210 /*
211 * Descriptions of the usages of the methods below can be found in
212 * the classes that use them. Briefly, a thread's "probe" value is
213 * a non-zero hash code that (probably) does not collide with
214 * other existing threads with respect to any power of two
215 * collision space. When it does collide, it is pseudo-randomly
216 * adjusted (using a Marsaglia XorShift). The nextSecondarySeed
217 * method is used in the same contexts as ThreadLocalRandom, but
218 * only for transient usages such as random adaptive spin/block
219 * sequences for which a cheap RNG suffices and for which it could
220 * in principle disrupt user-visible statistical properties of the
221 * main ThreadLocalRandom if we were to use it.
222 *
223 * Note: Because of package-protection issues, versions of some
224 * these methods also appear in some subpackage classes.
225 */
226
227 /**
228 * Returns the probe value for the current thread without forcing
229 * initialization. Note that invoking ThreadLocalRandom.current()
230 * can be used to force initialization on zero return.
231 */
232 static final int getProbe() {
233 return U.getInt(Thread.currentThread(), PROBE);
234 }
235
236 /**
237 * Pseudo-randomly advances and records the given probe value for the
238 * given thread.
239 */
240 static final int advanceProbe(int probe) {
241 probe ^= probe << 13; // xorshift
242 probe ^= probe >>> 17;
243 probe ^= probe << 5;
244 U.putInt(Thread.currentThread(), PROBE, probe);
245 return probe;
246 }
247
248 /**
249 * Returns the pseudo-randomly initialized or updated secondary seed.
250 */
251 static final int nextSecondarySeed() {
252 int r;
253 Thread t = Thread.currentThread();
254 if ((r = U.getInt(t, SECONDARY)) != 0) {
255 r ^= r << 13; // xorshift
256 r ^= r >>> 17;
257 r ^= r << 5;
258 }
259 else if ((r = mix32(seeder.getAndAdd(SEEDER_INCREMENT))) == 0)
260 r = 1; // avoid zero
261 U.putInt(t, SECONDARY, r);
262 return r;
263 }
264
265 // Support for other package-private ThreadLocal access
266
267 /**
268 * Erases ThreadLocals by nulling out Thread maps.
269 */
270 static final void eraseThreadLocals(Thread thread) {
271 U.putReference(thread, THREADLOCALS, null);
272 U.putReference(thread, INHERITABLETHREADLOCALS, null);
273 }
274
275 static final void setInheritedAccessControlContext(Thread thread,
276 @SuppressWarnings("removal") AccessControlContext acc) {
277 U.putReferenceRelease(thread, INHERITEDACCESSCONTROLCONTEXT, acc);
278 }
279
280 // Serialization support
281
282 private static final long serialVersionUID = -5851777807851030925L;
283
284 /**
285 * @serialField rnd long
286 * seed for random computations
287 * @serialField initialized boolean
288 * always true
289 */
290 private static final ObjectStreamField[] serialPersistentFields = {
291 new ObjectStreamField("rnd", long.class),
292 new ObjectStreamField("initialized", boolean.class),
293 };
294
295 /**
296 * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
297 * @param s the stream
298 * @throws java.io.IOException if an I/O error occurs
299 */
300 private void writeObject(java.io.ObjectOutputStream s)
301 throws java.io.IOException {
302
303 java.io.ObjectOutputStream.PutField fields = s.putFields();
304 fields.put("rnd", U.getLong(Thread.currentThread(), SEED));
305 fields.put("initialized", true);
306 s.writeFields();
307 }
308
309 /**
310 * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
311 * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
312 */
313 private Object readResolve() {
314 return current();
315 }
316
317 // Static initialization
318
319 /**
320 * The seed increment. This must be an odd value for the generator to
321 * have the maximum period (2 to the 64th power).
322 *
323 * The value 0x9e3779b97f4a7c15L is odd, and moreover consists of the
324 * first 64 bits of the fractional part of the golden ratio,
325 * which is known to generate good Weyl sequences.
326 */
327 private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
328
329 /**
330 * The increment for generating probe values.
331 */
332 private static final int PROBE_INCREMENT = 0x9e3779b9;
333
334 /**
335 * The increment of seeder per new instance.
336 */
337 private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
338
339 // IllegalArgumentException messages
340 static final String BAD_BOUND = "bound must be positive";
341 static final String BAD_RANGE = "bound must be greater than origin";
342 static final String BAD_SIZE = "size must be non-negative";
343
344 // Unsafe mechanics
345 private static final Unsafe U = Unsafe.getUnsafe();
346 private static final long SEED
347 = U.objectFieldOffset(Thread.class, "threadLocalRandomSeed");
348 private static final long PROBE
349 = U.objectFieldOffset(Thread.class, "threadLocalRandomProbe");
350 private static final long SECONDARY
351 = U.objectFieldOffset(Thread.class, "threadLocalRandomSecondarySeed");
352 private static final long THREADLOCALS
353 = U.objectFieldOffset(Thread.class, "threadLocals");
354 private static final long INHERITABLETHREADLOCALS
355 = U.objectFieldOffset(Thread.class, "inheritableThreadLocals");
356 private static final long INHERITEDACCESSCONTROLCONTEXT
357 = U.objectFieldOffset(Thread.class, "inheritedAccessControlContext");
358
359 /** Generates per-thread initialization/probe field */
360 private static final AtomicInteger probeGenerator = new AtomicInteger();
361
362 /** The common ThreadLocalRandom */
363 private static final ThreadLocalRandom instance = new ThreadLocalRandom();
364
365 /**
366 * The next seed for default constructors.
367 */
368 private static final AtomicLong seeder
369 = new AtomicLong(RandomSupport.mixMurmur64(System.currentTimeMillis()) ^
370 RandomSupport.mixMurmur64(System.nanoTime()));
371
372 // at end of <clinit> to survive static initialization circularity
373 static {
374 String sec = VM.getSavedProperty("java.util.secureRandomSeed");
375 if (Boolean.parseBoolean(sec)) {
376 byte[] seedBytes = java.security.SecureRandom.getSeed(8);
377 long s = (long)seedBytes[0] & 0xffL;
378 for (int i = 1; i < 8; ++i)
379 s = (s << 8) | ((long)seedBytes[i] & 0xffL);
380 seeder.set(s);
381 }
382 }
383
384 @SuppressWarnings("serial")
385 private static final class ThreadLocalRandomProxy extends Random {
386 static final Random PROXY = new ThreadLocalRandomProxy();
387
388 public int nextInt() {
389 return ThreadLocalRandom.current().nextInt();
390 }
391
392 public long nextLong() {
393 return ThreadLocalRandom.current().nextLong();
394 }
395 }
396
397 /**
398 * {@inheritDoc}
399 */
400 @Override
401 public boolean nextBoolean() {
402 return super.nextBoolean();
403 }
404
405 /**
406 * {@inheritDoc}
407 */
408 @Override
409 public int nextInt() {
410 return mix32(nextSeed());
411 }
412
413 /**
414 * {@inheritDoc}
415 * @throws IllegalArgumentException {@inheritDoc}
416 */
417 @Override
418 public int nextInt(int bound) {
419 return super.nextInt(bound);
420 }
421
422 /**
423 * {@inheritDoc}
424 * @throws IllegalArgumentException {@inheritDoc}
425 */
426 @Override
427 public int nextInt(int origin, int bound) {
428 return super.nextInt(origin, bound);
429 }
430
431 /**
432 * {@inheritDoc}
433 */
434 @Override
435 public long nextLong() {
436 return RandomSupport.mixMurmur64(nextSeed());
437 }
438
439 /**
440 * {@inheritDoc}
441 * @throws IllegalArgumentException {@inheritDoc}
442 */
443 @Override
444 public long nextLong(long bound) {
445 return super.nextLong(bound);
446 }
447
448 /**
449 * {@inheritDoc}
450 * @throws IllegalArgumentException {@inheritDoc}
451 */
452 @Override
453 public long nextLong(long origin, long bound) {
454 return super.nextLong(origin, bound);
455 }
456
457 /**
458 * {@inheritDoc}
459 */
460 @Override
461 public float nextFloat() {
462 return super.nextFloat();
463 }
464
465 /**
466 * {@inheritDoc}
467 * @throws IllegalArgumentException {@inheritDoc}
468 * @implNote {@inheritDoc}
469 */
470 @Override
471 public float nextFloat(float bound) {
472 return super.nextFloat(bound);
473 }
474
475 /**
476 * {@inheritDoc}
477 * @throws IllegalArgumentException {@inheritDoc}
478 * @implNote {@inheritDoc}
479 */
480 @Override
481 public float nextFloat(float origin, float bound) {
482 return super.nextFloat(origin, bound);
483 }
484
485 /**
486 * {@inheritDoc}
487 */
488 @Override
489 public double nextDouble() {
490 return super.nextDouble();
491 }
492
493 /**
494 * {@inheritDoc}
495 * @throws IllegalArgumentException {@inheritDoc}
496 * @implNote {@inheritDoc}
497 */
498 @Override
499 public double nextDouble(double bound) {
500 return super.nextDouble(bound);
501 }
502
503 /**
504 * {@inheritDoc}
505 * @throws IllegalArgumentException {@inheritDoc}
506 * @implNote {@inheritDoc}
507 */
508 @Override
509 public double nextDouble(double origin, double bound) {
510 return super.nextDouble(origin, bound);
511 }
512 /**
513 * {@inheritDoc}
514 * @throws IllegalArgumentException {@inheritDoc}
515 * @since 1.8
516 */
517 @Override
518 public IntStream ints(long streamSize) {
519 return AbstractSpliteratorGenerator.ints(ThreadLocalRandomProxy.PROXY, streamSize);
520 }
521
522 /**
523 * {@inheritDoc}
524 * @implNote This method is implemented to be equivalent to
525 * {@code ints(Long.MAX_VALUE)}.
526 * @since 1.8
527 */
528 @Override
529 public IntStream ints() {
530 return AbstractSpliteratorGenerator.ints(ThreadLocalRandomProxy.PROXY);
531 }
532
533 /**
534 * {@inheritDoc}
535 * @throws IllegalArgumentException {@inheritDoc}
536 * @since 1.8
537 */
538 @Override
539 public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
540 return AbstractSpliteratorGenerator.ints(ThreadLocalRandomProxy.PROXY, streamSize, randomNumberOrigin, randomNumberBound);
541 }
542
543 /**
544 * {@inheritDoc}
545 * @implNote This method is implemented to be equivalent to
546 * {@code ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
547 * @throws IllegalArgumentException {@inheritDoc}
548 * @since 1.8
549 */
550 @Override
551 public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
552 return AbstractSpliteratorGenerator.ints(ThreadLocalRandomProxy.PROXY, randomNumberOrigin, randomNumberBound);
553 }
554
555 /**
556 * {@inheritDoc}
557 * @throws IllegalArgumentException {@inheritDoc}
558 * @since 1.8
559 */
560 @Override
561 public LongStream longs(long streamSize) {
562 return AbstractSpliteratorGenerator.longs(ThreadLocalRandomProxy.PROXY, streamSize);
563 }
564
565 /**
566 * {@inheritDoc}
567 * @implNote This method is implemented to be equivalent to
568 * {@code longs(Long.MAX_VALUE)}.
569 * @since 1.8
570 */
571 @Override
572 public LongStream longs() {
573 return AbstractSpliteratorGenerator.longs(ThreadLocalRandomProxy.PROXY);
574 }
575
576 /**
577 * {@inheritDoc}
578 * @throws IllegalArgumentException {@inheritDoc}
579 * @since 1.8
580 */
581 @Override
582 public LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound) {
583 return AbstractSpliteratorGenerator.longs(ThreadLocalRandomProxy.PROXY, streamSize, randomNumberOrigin, randomNumberBound);
584 }
585
586 /**
587 * {@inheritDoc}
588 * @implNote This method is implemented to be equivalent to
589 * {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
590 * @throws IllegalArgumentException {@inheritDoc}
591 * @since 1.8
592 */
593 @Override
594 public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
595 return AbstractSpliteratorGenerator.longs(ThreadLocalRandomProxy.PROXY, randomNumberOrigin, randomNumberBound);
596 }
597
598 /**
599 * {@inheritDoc}
600 * @throws IllegalArgumentException {@inheritDoc}
601 * @since 1.8
602 */
603 @Override
604 public DoubleStream doubles(long streamSize) {
605 return AbstractSpliteratorGenerator.doubles(ThreadLocalRandomProxy.PROXY, streamSize);
606 }
607
608 /**
609 * {@inheritDoc}
610 * @implNote This method is implemented to be equivalent to
611 * {@code doubles(Long.MAX_VALUE)}.
612 * @since 1.8
613 */
614 @Override
615 public DoubleStream doubles() {
616 return AbstractSpliteratorGenerator.doubles(ThreadLocalRandomProxy.PROXY);
617 }
618
619 /**
620 * {@inheritDoc}
621 * @throws IllegalArgumentException {@inheritDoc}
622 * @since 1.8
623 */
624 @Override
625 public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
626 return AbstractSpliteratorGenerator.doubles(ThreadLocalRandomProxy.PROXY, streamSize, randomNumberOrigin, randomNumberBound);
627 }
628
629 /**
630 * {@inheritDoc}
631 * @implNote This method is implemented to be equivalent to
632 * {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
633 * @throws IllegalArgumentException {@inheritDoc}
634 * @since 1.8
635 */
636 @Override
637 public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
638 return AbstractSpliteratorGenerator.doubles(ThreadLocalRandomProxy.PROXY, randomNumberOrigin, randomNumberBound);
639 }
640
641 }