ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.66
Committed: Fri Nov 25 16:39:48 2022 UTC (17 months, 3 weeks ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.65: +1 -1 lines
Log Message:
whitespace

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 @RandomGeneratorProperties(
61 name = "ThreadLocalRandom",
62 i = 64, j = 0, k = 0,
63 equidistribution = 1
64 )
65 public final class ThreadLocalRandom extends Random {
66 /*
67 * This class implements the java.util.Random API (and subclasses
68 * Random) using a single static instance that accesses 64 bits of
69 * random number state held in class java.lang.Thread (field
70 * threadLocalRandomSeed). In doing so, it also provides a home
71 * for managing package-private utilities that rely on exactly the
72 * same state as needed to maintain the ThreadLocalRandom
73 * instances. We leverage the need for an initialization flag
74 * field to also use it as a "probe" -- a self-adjusting thread
75 * hash used for contention avoidance, as well as a secondary
76 * simpler (xorShift) random seed that is conservatively used to
77 * avoid otherwise surprising users by hijacking the
78 * ThreadLocalRandom sequence. The dual use is a marriage of
79 * convenience, but is a simple and efficient way of reducing
80 * application-level overhead and footprint of most concurrent
81 * programs. Even more opportunistically, we also define here
82 * other package-private utilities that access Thread class
83 * fields.
84 *
85 * Even though this class subclasses java.util.Random, it uses the
86 * same basic algorithm as java.util.SplittableRandom. (See its
87 * internal documentation for explanations, which are not repeated
88 * here.) Note that ThreadLocalRandom is not a "splittable" generator
89 * (it does not support the split method), but it behaves as if
90 * one instance of the SplittableRandom algorithm had been
91 * created for each thread, each with a distinct gamma parameter
92 * (calculated from the thread id).
93 *
94 * Because this class is in a different package than class Thread,
95 * field access methods use Unsafe to bypass access control rules.
96 * To conform to the requirements of the Random superclass
97 * constructor, the common static ThreadLocalRandom maintains an
98 * "initialized" field for the sake of rejecting user calls to
99 * setSeed while still allowing a call from constructor. Note
100 * that serialization is completely unnecessary because there is
101 * only a static singleton. But we generate a serial form
102 * containing "rnd" and "initialized" fields to ensure
103 * compatibility across versions.
104 *
105 * Implementations of non-core methods are mostly the same as in
106 * SplittableRandom, that were in part derived from a previous
107 * version of this class.
108 *
109 * This implementation of ThreadLocalRandom overrides the
110 * definition of the nextGaussian() method in the class Random,
111 * and instead uses the ziggurat-based algorithm that is the
112 * default for the RandomGenerator interface.
113 */
114
115 private static int mix32(long z) {
116 z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
117 return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
118 }
119
120 /**
121 * Field used only during singleton initialization.
122 * True when constructor completes.
123 */
124 boolean initialized;
125
126 /** Constructor used only for static singleton */
127 private ThreadLocalRandom() {
128 initialized = true; // false during super() call
129 }
130
131 /**
132 * Initialize Thread fields for the current thread. Called only
133 * when Thread.threadLocalRandomProbe is zero, indicating that a
134 * thread local seed value needs to be generated. Note that even
135 * though the initialization is purely thread-local, we need to
136 * rely on (static) atomic generators to initialize the values.
137 */
138 static final void localInit() {
139 int p = probeGenerator.addAndGet(PROBE_INCREMENT);
140 int probe = (p == 0) ? 1 : p; // skip 0
141 long seed = RandomSupport.mixMurmur64(seeder.getAndAdd(SEEDER_INCREMENT));
142 Thread t = Thread.currentThread();
143 U.putLong(t, SEED, seed);
144 U.putInt(t, PROBE, probe);
145 }
146
147 /**
148 * Returns the current thread's {@code ThreadLocalRandom} object.
149 * Methods of this object should be called only by the current thread,
150 * not by other threads.
151 *
152 * @return the current thread's {@code ThreadLocalRandom}
153 */
154 public static ThreadLocalRandom current() {
155 if (U.getInt(Thread.currentThread(), PROBE) == 0)
156 localInit();
157 return instance;
158 }
159
160 /**
161 * Throws {@code UnsupportedOperationException}. Setting seeds in
162 * this generator is not supported.
163 *
164 * @throws UnsupportedOperationException always
165 */
166 public void setSeed(long seed) {
167 // only allow call from super() constructor
168 if (initialized)
169 throw new UnsupportedOperationException();
170 }
171
172 /**
173 * Update the thread local seed value by adding to it the sum
174 * of {@code GOLDEN_GAMMA} (an odd value) and twice the thread id.
175 * This sum is always odd (to guarantee that the generator
176 * has maximum period) and is different for different threads.
177 * Because thread id values are allocated consecutively starting
178 * from 0, the high 32 bits of this sum will be the same as the
179 * high 32 bits of {@code GOLDEN_GAMMA} unless an extremely large
180 * number of threads have been created, and so the overall
181 * value added to the thread local seed value will have at least
182 * fourteen 01 and 10 transitions (see the documentation for the
183 * method {@code mixGamma} in class {@code SplittableRandom}),
184 * which should provide adequate statistical quality for
185 * applications likely to use {@code ThreadLocalRandom}.
186 */
187 final long nextSeed() {
188 Thread t; long r; // read and update per-thread seed
189 U.putLong(t = Thread.currentThread(), SEED,
190 r = U.getLong(t, SEED) + (t.getId() << 1) + GOLDEN_GAMMA);
191 return r;
192 }
193
194 /**
195 * Generates a pseudorandom number with the indicated number of
196 * low-order bits. Because this class has no subclasses, this
197 * method cannot be invoked or overridden.
198 *
199 * @param bits random bits
200 * @return the next pseudorandom value from this random number
201 * generator's sequence
202 */
203 protected int next(int bits) {
204 return nextInt() >>> (32 - bits);
205 }
206
207 // Within-package utilities
208
209 /*
210 * Descriptions of the usages of the methods below can be found in
211 * the classes that use them. Briefly, a thread's "probe" value is
212 * a non-zero hash code that (probably) does not collide with
213 * other existing threads with respect to any power of two
214 * collision space. When it does collide, it is pseudo-randomly
215 * adjusted (using a Marsaglia XorShift). The nextSecondarySeed
216 * method is used in the same contexts as ThreadLocalRandom, but
217 * only for transient usages such as random adaptive spin/block
218 * sequences for which a cheap RNG suffices and for which it could
219 * in principle disrupt user-visible statistical properties of the
220 * main ThreadLocalRandom if we were to use it.
221 *
222 * Note: Because of package-protection issues, versions of some
223 * these methods also appear in some subpackage classes.
224 */
225
226 /**
227 * Returns the probe value for the current thread without forcing
228 * initialization. Note that invoking ThreadLocalRandom.current()
229 * can be used to force initialization on zero return.
230 */
231 static final int getProbe() {
232 return U.getInt(Thread.currentThread(), PROBE);
233 }
234
235 /**
236 * Pseudo-randomly advances and records the given probe value for the
237 * given thread.
238 */
239 static final int advanceProbe(int probe) {
240 probe ^= probe << 13; // xorshift
241 probe ^= probe >>> 17;
242 probe ^= probe << 5;
243 U.putInt(Thread.currentThread(), PROBE, probe);
244 return probe;
245 }
246
247 /**
248 * Returns the pseudo-randomly initialized or updated secondary seed.
249 */
250 static final int nextSecondarySeed() {
251 int r;
252 Thread t = Thread.currentThread();
253 if ((r = U.getInt(t, SECONDARY)) != 0) {
254 r ^= r << 13; // xorshift
255 r ^= r >>> 17;
256 r ^= r << 5;
257 }
258 else if ((r = mix32(seeder.getAndAdd(SEEDER_INCREMENT))) == 0)
259 r = 1; // avoid zero
260 U.putInt(t, SECONDARY, r);
261 return r;
262 }
263
264 // Support for other package-private ThreadLocal access
265
266 /**
267 * Erases ThreadLocals by nulling out Thread maps.
268 */
269 static final void eraseThreadLocals(Thread thread) {
270 U.putReference(thread, THREADLOCALS, null);
271 U.putReference(thread, INHERITABLETHREADLOCALS, null);
272 }
273
274 static final void setInheritedAccessControlContext(Thread thread,
275 @SuppressWarnings("removal") AccessControlContext acc) {
276 U.putReferenceRelease(thread, INHERITEDACCESSCONTROLCONTEXT, acc);
277 }
278
279 // Serialization support
280
281 private static final long serialVersionUID = -5851777807851030925L;
282
283 /**
284 * @serialField rnd long
285 * seed for random computations
286 * @serialField initialized boolean
287 * always true
288 */
289 private static final ObjectStreamField[] serialPersistentFields = {
290 new ObjectStreamField("rnd", long.class),
291 new ObjectStreamField("initialized", boolean.class),
292 };
293
294 /**
295 * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
296 * @param s the stream
297 * @throws java.io.IOException if an I/O error occurs
298 */
299 private void writeObject(java.io.ObjectOutputStream s)
300 throws java.io.IOException {
301
302 java.io.ObjectOutputStream.PutField fields = s.putFields();
303 fields.put("rnd", U.getLong(Thread.currentThread(), SEED));
304 fields.put("initialized", true);
305 s.writeFields();
306 }
307
308 /**
309 * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
310 * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
311 */
312 private Object readResolve() {
313 return current();
314 }
315
316 // Static initialization
317
318 /**
319 * The seed increment. This must be an odd value for the generator to
320 * have the maximum period (2 to the 64th power).
321 *
322 * The value 0x9e3779b97f4a7c15L is odd, and moreover consists of the
323 * first 64 bits of the fractional part of the golden ratio,
324 * which is known to generate good Weyl sequences.
325 */
326 private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
327
328 /**
329 * The increment for generating probe values.
330 */
331 private static final int PROBE_INCREMENT = 0x9e3779b9;
332
333 /**
334 * The increment of seeder per new instance.
335 */
336 private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
337
338 // IllegalArgumentException messages
339 static final String BAD_BOUND = "bound must be positive";
340 static final String BAD_RANGE = "bound must be greater than origin";
341 static final String BAD_SIZE = "size must be non-negative";
342
343 // Unsafe mechanics
344 private static final Unsafe U = Unsafe.getUnsafe();
345 private static final long SEED
346 = U.objectFieldOffset(Thread.class, "threadLocalRandomSeed");
347 private static final long PROBE
348 = U.objectFieldOffset(Thread.class, "threadLocalRandomProbe");
349 private static final long SECONDARY
350 = U.objectFieldOffset(Thread.class, "threadLocalRandomSecondarySeed");
351 private static final long THREADLOCALS
352 = U.objectFieldOffset(Thread.class, "threadLocals");
353 private static final long INHERITABLETHREADLOCALS
354 = U.objectFieldOffset(Thread.class, "inheritableThreadLocals");
355 private static final long INHERITEDACCESSCONTROLCONTEXT
356 = U.objectFieldOffset(Thread.class, "inheritedAccessControlContext");
357
358 /** Generates per-thread initialization/probe field */
359 private static final AtomicInteger probeGenerator = new AtomicInteger();
360
361 /** The common ThreadLocalRandom */
362 private static final ThreadLocalRandom instance = new ThreadLocalRandom();
363
364 /**
365 * The next seed for default constructors.
366 */
367 private static final AtomicLong seeder
368 = new AtomicLong(RandomSupport.mixMurmur64(System.currentTimeMillis()) ^
369 RandomSupport.mixMurmur64(System.nanoTime()));
370
371 // at end of <clinit> to survive static initialization circularity
372 static {
373 String sec = VM.getSavedProperty("java.util.secureRandomSeed");
374 if (Boolean.parseBoolean(sec)) {
375 byte[] seedBytes = java.security.SecureRandom.getSeed(8);
376 long s = (long)seedBytes[0] & 0xffL;
377 for (int i = 1; i < 8; ++i)
378 s = (s << 8) | ((long)seedBytes[i] & 0xffL);
379 seeder.set(s);
380 }
381 }
382
383 @SuppressWarnings("serial")
384 private static final class ThreadLocalRandomProxy extends Random {
385 static final Random PROXY = new ThreadLocalRandomProxy();
386
387 public int nextInt() {
388 return ThreadLocalRandom.current().nextInt();
389 }
390
391 public long nextLong() {
392 return ThreadLocalRandom.current().nextLong();
393 }
394 }
395
396 /**
397 * {@inheritDoc}
398 */
399 @Override
400 public boolean nextBoolean() {
401 return super.nextBoolean();
402 }
403
404 /**
405 * {@inheritDoc}
406 */
407 @Override
408 public int nextInt() {
409 return mix32(nextSeed());
410 }
411
412 /**
413 * {@inheritDoc}
414 * @throws IllegalArgumentException {@inheritDoc}
415 */
416 @Override
417 public int nextInt(int bound) {
418 return super.nextInt(bound);
419 }
420
421 /**
422 * {@inheritDoc}
423 * @throws IllegalArgumentException {@inheritDoc}
424 */
425 @Override
426 public int nextInt(int origin, int bound) {
427 return super.nextInt(origin, bound);
428 }
429
430 /**
431 * {@inheritDoc}
432 */
433 @Override
434 public long nextLong() {
435 return RandomSupport.mixMurmur64(nextSeed());
436 }
437
438 /**
439 * {@inheritDoc}
440 * @throws IllegalArgumentException {@inheritDoc}
441 */
442 @Override
443 public long nextLong(long bound) {
444 return super.nextLong(bound);
445 }
446
447 /**
448 * {@inheritDoc}
449 * @throws IllegalArgumentException {@inheritDoc}
450 */
451 @Override
452 public long nextLong(long origin, long bound) {
453 return super.nextLong(origin, bound);
454 }
455
456 /**
457 * {@inheritDoc}
458 */
459 @Override
460 public float nextFloat() {
461 return super.nextFloat();
462 }
463
464 /**
465 * {@inheritDoc}
466 * @throws IllegalArgumentException {@inheritDoc}
467 * @implNote {@inheritDoc}
468 */
469 @Override
470 public float nextFloat(float bound) {
471 return super.nextFloat(bound);
472 }
473
474 /**
475 * {@inheritDoc}
476 * @throws IllegalArgumentException {@inheritDoc}
477 * @implNote {@inheritDoc}
478 */
479 @Override
480 public float nextFloat(float origin, float bound) {
481 return super.nextFloat(origin, bound);
482 }
483
484 /**
485 * {@inheritDoc}
486 */
487 @Override
488 public double nextDouble() {
489 return super.nextDouble();
490 }
491
492 /**
493 * {@inheritDoc}
494 * @throws IllegalArgumentException {@inheritDoc}
495 * @implNote {@inheritDoc}
496 */
497 @Override
498 public double nextDouble(double bound) {
499 return super.nextDouble(bound);
500 }
501
502 /**
503 * {@inheritDoc}
504 * @throws IllegalArgumentException {@inheritDoc}
505 * @implNote {@inheritDoc}
506 */
507 @Override
508 public double nextDouble(double origin, double bound) {
509 return super.nextDouble(origin, bound);
510 }
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 }