ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.20
Committed: Tue Aug 13 17:13:49 2013 UTC (10 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.19: +3 -3 lines
Log Message:
javadoc touchups

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.Spliterator;
12 import java.util.concurrent.atomic.AtomicInteger;
13 import java.util.concurrent.atomic.AtomicLong;
14 import java.util.function.DoubleConsumer;
15 import java.util.function.IntConsumer;
16 import java.util.function.LongConsumer;
17 import java.util.stream.DoubleStream;
18 import java.util.stream.IntStream;
19 import java.util.stream.LongStream;
20 import java.util.stream.StreamSupport;
21
22 /**
23 * A random number generator isolated to the current thread. Like the
24 * global {@link java.util.Random} generator used by the {@link
25 * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
26 * with an internally generated seed that may not otherwise be
27 * modified. When applicable, use of {@code ThreadLocalRandom} rather
28 * than shared {@code Random} objects in concurrent programs will
29 * typically encounter much less overhead and contention. Use of
30 * {@code ThreadLocalRandom} is particularly appropriate when multiple
31 * tasks (for example, each a {@link ForkJoinTask}) use random numbers
32 * in parallel in thread pools.
33 *
34 * <p>Usages of this class should typically be of the form:
35 * {@code ThreadLocalRandom.current().nextX(...)} (where
36 * {@code X} is {@code Int}, {@code Long}, etc).
37 * When all usages are of this form, it is never possible to
38 * accidently share a {@code ThreadLocalRandom} across multiple threads.
39 *
40 * <p>This class also provides additional commonly used bounded random
41 * generation methods.
42 *
43 * @since 1.7
44 * @author Doug Lea
45 */
46 public class ThreadLocalRandom extends Random {
47 /*
48 * This class implements the java.util.Random API (and subclasses
49 * Random) using a single static instance that accesses random
50 * number state held in class Thread (primarily, field
51 * threadLocalRandomSeed). In doing so, it also provides a home
52 * for managing package-private utilities that rely on exactly the
53 * same state as needed to maintain the ThreadLocalRandom
54 * instances. We leverage the need for an initialization flag
55 * field to also use it as a "probe" -- a self-adjusting thread
56 * hash used for contention avoidance, as well as a secondary
57 * simpler (xorShift) random seed that is conservatively used to
58 * avoid otherwise surprising users by hijacking the
59 * ThreadLocalRandom sequence. The dual use is a marriage of
60 * convenience, but is a simple and efficient way of reducing
61 * application-level overhead and footprint of most concurrent
62 * programs.
63 *
64 * Even though this class subclasses java.util.Random, it uses the
65 * same basic algorithm as java.util.SplittableRandom. (See its
66 * internal documentation for explanations, which are not repeated
67 * here.) Because ThreadLocalRandoms are not splittable
68 * though, we use only a single 64bit gamma.
69 *
70 * Because this class is in a different package than class Thread,
71 * field access methods use Unsafe to bypass access control rules.
72 * To conform to the requirements of the Random superclass
73 * constructor, the common static ThreadLocalRandom maintains an
74 * "initialized" field for the sake of rejecting user calls to
75 * setSeed while still allowing a call from constructor. Note
76 * that serialization is completely unnecessary because there is
77 * only a static singleton. But we generate a serial form
78 * containing "rnd" and "initialized" fields to ensure
79 * compatibility across versions.
80 *
81 * Implementations of non-core methods are mostly the same as in
82 * SplittableRandom, that were in part derived from a previous
83 * version of this class.
84 *
85 * The nextLocalGaussian ThreadLocal supports the very rarely used
86 * nextGaussian method by providing a holder for the second of a
87 * pair of them. As is true for the base class version of this
88 * method, this time/space tradeoff is probably never worthwhile,
89 * but we provide identical statistical properties.
90 */
91
92 /** Generates per-thread initialization/probe field */
93 private static final AtomicInteger probeGenerator =
94 new AtomicInteger();
95
96 /**
97 * The next seed for default constructors.
98 */
99 private static final AtomicLong seedGenerator =
100 new AtomicLong(mix64(System.currentTimeMillis()) ^
101 mix64(System.nanoTime()));
102
103 /**
104 * The seed increment
105 */
106 private static final long GAMMA = 0x9e3779b97f4a7c15L;
107
108 /**
109 * The increment for generating probe values
110 */
111 private static final int PROBE_INCREMENT = 0x9e3779b9;
112
113 /**
114 * The increment of seedGenerator per new instance
115 */
116 private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
117
118 // Constants from SplittableRandom
119 private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
120 private static final float FLOAT_UNIT = 1.0f / (1 << 24);
121
122 /** Rarely-used holder for the second of a pair of Gaussians */
123 private static final ThreadLocal<Double> nextLocalGaussian =
124 new ThreadLocal<Double>();
125
126 private static long mix64(long z) {
127 z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
128 z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
129 return z ^ (z >>> 33);
130 }
131
132 private static int mix32(long z) {
133 z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
134 return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
135 }
136
137 /**
138 * Field used only during singleton initialization.
139 * True when constructor completes.
140 */
141 boolean initialized;
142
143 /** Constructor used only for static singleton */
144 private ThreadLocalRandom() {
145 initialized = true; // false during super() call
146 }
147
148 /** The common ThreadLocalRandom */
149 static final ThreadLocalRandom instance = new ThreadLocalRandom();
150
151 /**
152 * Initialize Thread fields for the current thread. Called only
153 * when Thread.threadLocalRandomProbe is zero, indicating that a
154 * thread local seed value needs to be generated. Note that even
155 * though the initialization is purely thread-local, we need to
156 * rely on (static) atomic generators to initialize the values.
157 */
158 static final void localInit() {
159 int p = probeGenerator.addAndGet(PROBE_INCREMENT);
160 int probe = (p == 0) ? 1 : p; // skip 0
161 long seed = mix64(seedGenerator.getAndAdd(SEEDER_INCREMENT));
162 Thread t = Thread.currentThread();
163 UNSAFE.putLong(t, SEED, seed);
164 UNSAFE.putInt(t, PROBE, probe);
165 }
166
167 /**
168 * Returns the current thread's {@code ThreadLocalRandom}.
169 *
170 * @return the current thread's {@code ThreadLocalRandom}
171 */
172 public static ThreadLocalRandom current() {
173 if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
174 localInit();
175 return instance;
176 }
177
178 /**
179 * Throws {@code UnsupportedOperationException}. Setting seeds in
180 * this generator is not supported.
181 *
182 * @throws UnsupportedOperationException always
183 */
184 public void setSeed(long seed) {
185 // only allow call from super() constructor
186 if (initialized)
187 throw new UnsupportedOperationException();
188 }
189
190 final long nextSeed() {
191 Thread t; long r; // read and update per-thread seed
192 UNSAFE.putLong(t = Thread.currentThread(), SEED,
193 r = UNSAFE.getLong(t, SEED) + GAMMA);
194 return r;
195 }
196
197 // We must define this, but never use it.
198 protected int next(int bits) {
199 return (int)(mix64(nextSeed()) >>> (64 - bits));
200 }
201
202 // IllegalArgumentException messages
203 static final String BadBound = "bound must be positive";
204 static final String BadRange = "bound must be greater than origin";
205 static final String BadSize = "size must be non-negative";
206
207 /**
208 * The form of nextLong used by LongStream Spliterators. If
209 * origin is greater than bound, acts as unbounded form of
210 * nextLong, else as bounded form.
211 *
212 * @param origin the least value, unless greater than bound
213 * @param bound the upper bound (exclusive), must not equal origin
214 * @return a pseudorandom value
215 */
216 final long internalNextLong(long origin, long bound) {
217 long r = mix64(nextSeed());
218 if (origin < bound) {
219 long n = bound - origin, m = n - 1;
220 if ((n & m) == 0L) // power of two
221 r = (r & m) + origin;
222 else if (n > 0L) { // reject over-represented candidates
223 for (long u = r >>> 1; // ensure nonnegative
224 u + m - (r = u % n) < 0L; // rejection check
225 u = mix64(nextSeed()) >>> 1) // retry
226 ;
227 r += origin;
228 }
229 else { // range not representable as long
230 while (r < origin || r >= bound)
231 r = mix64(nextSeed());
232 }
233 }
234 return r;
235 }
236
237 /**
238 * The form of nextInt used by IntStream Spliterators.
239 * Exactly the same as long version, except for types.
240 *
241 * @param origin the least value, unless greater than bound
242 * @param bound the upper bound (exclusive), must not equal origin
243 * @return a pseudorandom value
244 */
245 final int internalNextInt(int origin, int bound) {
246 int r = mix32(nextSeed());
247 if (origin < bound) {
248 int n = bound - origin, m = n - 1;
249 if ((n & m) == 0)
250 r = (r & m) + origin;
251 else if (n > 0) {
252 for (int u = r >>> 1;
253 u + m - (r = u % n) < 0;
254 u = mix32(nextSeed()) >>> 1)
255 ;
256 r += origin;
257 }
258 else {
259 while (r < origin || r >= bound)
260 r = mix32(nextSeed());
261 }
262 }
263 return r;
264 }
265
266 /**
267 * The form of nextDouble used by DoubleStream Spliterators.
268 *
269 * @param origin the least value, unless greater than bound
270 * @param bound the upper bound (exclusive), must not equal origin
271 * @return a pseudorandom value
272 */
273 final double internalNextDouble(double origin, double bound) {
274 double r = (nextLong() >>> 11) * DOUBLE_UNIT;
275 if (origin < bound) {
276 r = r * (bound - origin) + origin;
277 if (r >= bound) // correct for rounding
278 r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
279 }
280 return r;
281 }
282
283 /**
284 * Returns a pseudorandom {@code int} value.
285 *
286 * @return a pseudorandom {@code int} value
287 */
288 public int nextInt() {
289 return mix32(nextSeed());
290 }
291
292 /**
293 * Returns a pseudorandom {@code int} value between zero (inclusive)
294 * and the specified bound (exclusive).
295 *
296 * @param bound the bound on the random number to be returned. Must be
297 * positive.
298 * @return a pseudorandom {@code int} value between zero
299 * (inclusive) and the bound (exclusive)
300 * @throws IllegalArgumentException if {@code bound} is not positive
301 */
302 public int nextInt(int bound) {
303 if (bound <= 0)
304 throw new IllegalArgumentException(BadBound);
305 int r = mix32(nextSeed());
306 int m = bound - 1;
307 if ((bound & m) == 0) // power of two
308 r &= m;
309 else { // reject over-represented candidates
310 for (int u = r >>> 1;
311 u + m - (r = u % bound) < 0;
312 u = mix32(nextSeed()) >>> 1)
313 ;
314 }
315 return r;
316 }
317
318 /**
319 * Returns a pseudorandom {@code int} value between the specified
320 * origin (inclusive) and the specified bound (exclusive).
321 *
322 * @param origin the least value returned
323 * @param bound the upper bound (exclusive)
324 * @return a pseudorandom {@code int} value between the origin
325 * (inclusive) and the bound (exclusive)
326 * @throws IllegalArgumentException if {@code origin} is greater than
327 * or equal to {@code bound}
328 */
329 public int nextInt(int origin, int bound) {
330 if (origin >= bound)
331 throw new IllegalArgumentException(BadRange);
332 return internalNextInt(origin, bound);
333 }
334
335 /**
336 * Returns a pseudorandom {@code long} value.
337 *
338 * @return a pseudorandom {@code long} value
339 */
340 public long nextLong() {
341 return mix64(nextSeed());
342 }
343
344 /**
345 * Returns a pseudorandom {@code long} value between zero (inclusive)
346 * and the specified bound (exclusive).
347 *
348 * @param bound the bound on the random number to be returned. Must be
349 * positive.
350 * @return a pseudorandom {@code long} value between zero
351 * (inclusive) and the bound (exclusive)
352 * @throws IllegalArgumentException if {@code bound} is not positive
353 */
354 public long nextLong(long bound) {
355 if (bound <= 0)
356 throw new IllegalArgumentException(BadBound);
357 long r = mix64(nextSeed());
358 long m = bound - 1;
359 if ((bound & m) == 0L) // power of two
360 r &= m;
361 else { // reject over-represented candidates
362 for (long u = r >>> 1;
363 u + m - (r = u % bound) < 0L;
364 u = mix64(nextSeed()) >>> 1)
365 ;
366 }
367 return r;
368 }
369
370 /**
371 * Returns a pseudorandom {@code long} value between the specified
372 * origin (inclusive) and the specified bound (exclusive).
373 *
374 * @param origin the least value returned
375 * @param bound the upper bound (exclusive)
376 * @return a pseudorandom {@code long} value between the origin
377 * (inclusive) and the bound (exclusive)
378 * @throws IllegalArgumentException if {@code origin} is greater than
379 * or equal to {@code bound}
380 */
381 public long nextLong(long origin, long bound) {
382 if (origin >= bound)
383 throw new IllegalArgumentException(BadRange);
384 return internalNextLong(origin, bound);
385 }
386
387 /**
388 * Returns a pseudorandom {@code double} value between zero
389 * (inclusive) and one (exclusive).
390 *
391 * @return a pseudorandom {@code double} value between zero
392 * (inclusive) and one (exclusive)
393 */
394 public double nextDouble() {
395 return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
396 }
397
398 /**
399 * Returns a pseudorandom {@code double} value between 0.0
400 * (inclusive) and the specified bound (exclusive).
401 *
402 * @param bound the bound on the random number to be returned. Must be
403 * positive.
404 * @return a pseudorandom {@code double} value between zero
405 * (inclusive) and the bound (exclusive)
406 * @throws IllegalArgumentException if {@code bound} is not positive
407 */
408 public double nextDouble(double bound) {
409 if (!(bound > 0.0))
410 throw new IllegalArgumentException(BadBound);
411 double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
412 return (result < bound) ? result : // correct for rounding
413 Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
414 }
415
416 /**
417 * Returns a pseudorandom {@code double} value between the specified
418 * origin (inclusive) and bound (exclusive).
419 *
420 * @param origin the least value returned
421 * @param bound the upper bound
422 * @return a pseudorandom {@code double} value between the origin
423 * (inclusive) and the bound (exclusive)
424 * @throws IllegalArgumentException if {@code origin} is greater than
425 * or equal to {@code bound}
426 */
427 public double nextDouble(double origin, double bound) {
428 if (!(origin < bound))
429 throw new IllegalArgumentException(BadRange);
430 return internalNextDouble(origin, bound);
431 }
432
433 /**
434 * Returns a pseudorandom {@code boolean} value.
435 *
436 * @return a pseudorandom {@code boolean} value
437 */
438 public boolean nextBoolean() {
439 return mix32(nextSeed()) < 0;
440 }
441
442 /**
443 * Returns a pseudorandom {@code float} value between zero
444 * (inclusive) and one (exclusive).
445 *
446 * @return a pseudorandom {@code float} value between zero
447 * (inclusive) and one (exclusive)
448 */
449 public float nextFloat() {
450 return (mix32(nextSeed()) >>> 8) * FLOAT_UNIT;
451 }
452
453 public double nextGaussian() {
454 // Use nextLocalGaussian instead of nextGaussian field
455 Double d = nextLocalGaussian.get();
456 if (d != null) {
457 nextLocalGaussian.set(null);
458 return d.doubleValue();
459 }
460 double v1, v2, s;
461 do {
462 v1 = 2 * nextDouble() - 1; // between -1 and 1
463 v2 = 2 * nextDouble() - 1; // between -1 and 1
464 s = v1 * v1 + v2 * v2;
465 } while (s >= 1 || s == 0);
466 double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
467 nextLocalGaussian.set(new Double(v2 * multiplier));
468 return v1 * multiplier;
469 }
470
471 @Override
472 public DoubleStream gaussians() {
473 return DoubleStream.generate(() -> current().nextGaussian());
474 }
475
476 // stream methods, coded in a way intended to better isolate for
477 // maintenance purposes the small differences across forms.
478
479 /**
480 * Returns a stream producing the given {@code streamSize} number of
481 * pseudorandom {@code int} values.
482 *
483 * @param streamSize the number of values to generate
484 * @return a stream of pseudorandom {@code int} values
485 * @throws IllegalArgumentException if {@code streamSize} is
486 * less than zero
487 */
488 public IntStream ints(long streamSize) {
489 if (streamSize < 0L)
490 throw new IllegalArgumentException(BadSize);
491 return StreamSupport.intStream
492 (new RandomIntsSpliterator
493 (0L, streamSize, Integer.MAX_VALUE, 0),
494 false);
495 }
496
497 /**
498 * Returns an effectively unlimited stream of pseudorandom {@code int}
499 * values.
500 *
501 * @implNote This method is implemented to be equivalent to {@code
502 * ints(Long.MAX_VALUE)}.
503 *
504 * @return a stream of pseudorandom {@code int} values
505 */
506 public IntStream ints() {
507 return StreamSupport.intStream
508 (new RandomIntsSpliterator
509 (0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
510 false);
511 }
512
513 /**
514 * Returns a stream producing the given {@code streamSize} number of
515 * pseudorandom {@code int} values, each conforming to the given
516 * origin and bound.
517 *
518 * @param streamSize the number of values to generate
519 * @param randomNumberOrigin the origin of each random value
520 * @param randomNumberBound the bound of each random value
521 * @return a stream of pseudorandom {@code int} values,
522 * each with the given origin and bound
523 * @throws IllegalArgumentException if {@code streamSize} is
524 * less than zero, or {@code randomNumberOrigin}
525 * is greater than or equal to {@code randomNumberBound}
526 */
527 public IntStream ints(long streamSize, int randomNumberOrigin,
528 int randomNumberBound) {
529 if (streamSize < 0L)
530 throw new IllegalArgumentException(BadSize);
531 if (randomNumberOrigin >= randomNumberBound)
532 throw new IllegalArgumentException(BadRange);
533 return StreamSupport.intStream
534 (new RandomIntsSpliterator
535 (0L, streamSize, randomNumberOrigin, randomNumberBound),
536 false);
537 }
538
539 /**
540 * Returns an effectively unlimited stream of pseudorandom {@code
541 * int} values, each conforming to the given origin and bound.
542 *
543 * @implNote This method is implemented to be equivalent to {@code
544 * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
545 *
546 * @param randomNumberOrigin the origin of each random value
547 * @param randomNumberBound the bound of each random value
548 * @return a stream of pseudorandom {@code int} values,
549 * each with the given origin and bound
550 * @throws IllegalArgumentException if {@code randomNumberOrigin}
551 * is greater than or equal to {@code randomNumberBound}
552 */
553 public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
554 if (randomNumberOrigin >= randomNumberBound)
555 throw new IllegalArgumentException(BadRange);
556 return StreamSupport.intStream
557 (new RandomIntsSpliterator
558 (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
559 false);
560 }
561
562 /**
563 * Returns a stream producing the given {@code streamSize} number of
564 * pseudorandom {@code long} values.
565 *
566 * @param streamSize the number of values to generate
567 * @return a stream of pseudorandom {@code long} values
568 * @throws IllegalArgumentException if {@code streamSize} is
569 * less than zero
570 */
571 public LongStream longs(long streamSize) {
572 if (streamSize < 0L)
573 throw new IllegalArgumentException(BadSize);
574 return StreamSupport.longStream
575 (new RandomLongsSpliterator
576 (0L, streamSize, Long.MAX_VALUE, 0L),
577 false);
578 }
579
580 /**
581 * Returns an effectively unlimited stream of pseudorandom {@code long}
582 * values.
583 *
584 * @implNote This method is implemented to be equivalent to {@code
585 * longs(Long.MAX_VALUE)}.
586 *
587 * @return a stream of pseudorandom {@code long} values
588 */
589 public LongStream longs() {
590 return StreamSupport.longStream
591 (new RandomLongsSpliterator
592 (0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
593 false);
594 }
595
596 /**
597 * Returns a stream producing the given {@code streamSize} number of
598 * pseudorandom {@code long} values, each conforming to the
599 * given origin and bound.
600 *
601 * @param streamSize the number of values to generate
602 * @param randomNumberOrigin the origin of each random value
603 * @param randomNumberBound the bound of each random value
604 * @return a stream of pseudorandom {@code long} values,
605 * each with the given origin and bound
606 * @throws IllegalArgumentException if {@code streamSize} is
607 * less than zero, or {@code randomNumberOrigin}
608 * is greater than or equal to {@code randomNumberBound}
609 */
610 public LongStream longs(long streamSize, long randomNumberOrigin,
611 long randomNumberBound) {
612 if (streamSize < 0L)
613 throw new IllegalArgumentException(BadSize);
614 if (randomNumberOrigin >= randomNumberBound)
615 throw new IllegalArgumentException(BadRange);
616 return StreamSupport.longStream
617 (new RandomLongsSpliterator
618 (0L, streamSize, randomNumberOrigin, randomNumberBound),
619 false);
620 }
621
622 /**
623 * Returns an effectively unlimited stream of pseudorandom {@code
624 * long} values, each conforming to the given origin and bound.
625 *
626 * @implNote This method is implemented to be equivalent to {@code
627 * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
628 *
629 * @param randomNumberOrigin the origin of each random value
630 * @param randomNumberBound the bound of each random value
631 * @return a stream of pseudorandom {@code long} values,
632 * each with the given origin and bound
633 * @throws IllegalArgumentException if {@code randomNumberOrigin}
634 * is greater than or equal to {@code randomNumberBound}
635 */
636 public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
637 if (randomNumberOrigin >= randomNumberBound)
638 throw new IllegalArgumentException(BadRange);
639 return StreamSupport.longStream
640 (new RandomLongsSpliterator
641 (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
642 false);
643 }
644
645 /**
646 * Returns a stream producing the given {@code streamSize} number of
647 * pseudorandom {@code double} values, each between zero
648 * (inclusive) and one (exclusive).
649 *
650 * @param streamSize the number of values to generate
651 * @return a stream of {@code double} values
652 * @throws IllegalArgumentException if {@code streamSize} is
653 * less than zero
654 */
655 public DoubleStream doubles(long streamSize) {
656 if (streamSize < 0L)
657 throw new IllegalArgumentException(BadSize);
658 return StreamSupport.doubleStream
659 (new RandomDoublesSpliterator
660 (0L, streamSize, Double.MAX_VALUE, 0.0),
661 false);
662 }
663
664 /**
665 * Returns an effectively unlimited stream of pseudorandom {@code
666 * double} values, each between zero (inclusive) and one
667 * (exclusive).
668 *
669 * @implNote This method is implemented to be equivalent to {@code
670 * doubles(Long.MAX_VALUE)}.
671 *
672 * @return a stream of pseudorandom {@code double} values
673 */
674 public DoubleStream doubles() {
675 return StreamSupport.doubleStream
676 (new RandomDoublesSpliterator
677 (0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
678 false);
679 }
680
681 /**
682 * Returns a stream producing the given {@code streamSize} number of
683 * pseudorandom {@code double} values, each conforming to the
684 * given origin and bound.
685 *
686 * @param streamSize the number of values to generate
687 * @param randomNumberOrigin the origin of each random value
688 * @param randomNumberBound the bound of each random value
689 * @return a stream of pseudorandom {@code double} values,
690 * each with the given origin and bound
691 * @throws IllegalArgumentException if {@code streamSize} is
692 * less than zero
693 * @throws IllegalArgumentException if {@code randomNumberOrigin}
694 * is greater than or equal to {@code randomNumberBound}
695 */
696 public DoubleStream doubles(long streamSize, double randomNumberOrigin,
697 double randomNumberBound) {
698 if (streamSize < 0L)
699 throw new IllegalArgumentException(BadSize);
700 if (!(randomNumberOrigin < randomNumberBound))
701 throw new IllegalArgumentException(BadRange);
702 return StreamSupport.doubleStream
703 (new RandomDoublesSpliterator
704 (0L, streamSize, randomNumberOrigin, randomNumberBound),
705 false);
706 }
707
708 /**
709 * Returns an effectively unlimited stream of pseudorandom {@code
710 * double} values, each conforming to the given origin and bound.
711 *
712 * @implNote This method is implemented to be equivalent to {@code
713 * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
714 *
715 * @param randomNumberOrigin the origin of each random value
716 * @param randomNumberBound the bound of each random value
717 * @return a stream of pseudorandom {@code double} values,
718 * each with the given origin and bound
719 * @throws IllegalArgumentException if {@code randomNumberOrigin}
720 * is greater than or equal to {@code randomNumberBound}
721 */
722 public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
723 if (!(randomNumberOrigin < randomNumberBound))
724 throw new IllegalArgumentException(BadRange);
725 return StreamSupport.doubleStream
726 (new RandomDoublesSpliterator
727 (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
728 false);
729 }
730
731 /**
732 * Spliterator for int streams. We multiplex the four int
733 * versions into one class by treating a bound less than origin as
734 * unbounded, and also by treating "infinite" as equivalent to
735 * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
736 * approach. The long and double versions of this class are
737 * identical except for types.
738 */
739 static final class RandomIntsSpliterator implements Spliterator.OfInt {
740 long index;
741 final long fence;
742 final int origin;
743 final int bound;
744 RandomIntsSpliterator(long index, long fence,
745 int origin, int bound) {
746 this.index = index; this.fence = fence;
747 this.origin = origin; this.bound = bound;
748 }
749
750 public RandomIntsSpliterator trySplit() {
751 long i = index, m = (i + fence) >>> 1;
752 return (m <= i) ? null :
753 new RandomIntsSpliterator(i, index = m, origin, bound);
754 }
755
756 public long estimateSize() {
757 return fence - index;
758 }
759
760 public int characteristics() {
761 return (Spliterator.SIZED | Spliterator.SUBSIZED |
762 Spliterator.NONNULL | Spliterator.IMMUTABLE);
763 }
764
765 public boolean tryAdvance(IntConsumer consumer) {
766 if (consumer == null) throw new NullPointerException();
767 long i = index, f = fence;
768 if (i < f) {
769 consumer.accept(ThreadLocalRandom.current().internalNextInt(origin, bound));
770 index = i + 1;
771 return true;
772 }
773 return false;
774 }
775
776 public void forEachRemaining(IntConsumer consumer) {
777 if (consumer == null) throw new NullPointerException();
778 long i = index, f = fence;
779 if (i < f) {
780 index = f;
781 int o = origin, b = bound;
782 ThreadLocalRandom rng = ThreadLocalRandom.current();
783 do {
784 consumer.accept(rng.internalNextInt(o, b));
785 } while (++i < f);
786 }
787 }
788 }
789
790 /**
791 * Spliterator for long streams.
792 */
793 static final class RandomLongsSpliterator implements Spliterator.OfLong {
794 long index;
795 final long fence;
796 final long origin;
797 final long bound;
798 RandomLongsSpliterator(long index, long fence,
799 long origin, long bound) {
800 this.index = index; this.fence = fence;
801 this.origin = origin; this.bound = bound;
802 }
803
804 public RandomLongsSpliterator trySplit() {
805 long i = index, m = (i + fence) >>> 1;
806 return (m <= i) ? null :
807 new RandomLongsSpliterator(i, index = m, origin, bound);
808 }
809
810 public long estimateSize() {
811 return fence - index;
812 }
813
814 public int characteristics() {
815 return (Spliterator.SIZED | Spliterator.SUBSIZED |
816 Spliterator.NONNULL | Spliterator.IMMUTABLE);
817 }
818
819 public boolean tryAdvance(LongConsumer consumer) {
820 if (consumer == null) throw new NullPointerException();
821 long i = index, f = fence;
822 if (i < f) {
823 consumer.accept(ThreadLocalRandom.current().internalNextLong(origin, bound));
824 index = i + 1;
825 return true;
826 }
827 return false;
828 }
829
830 public void forEachRemaining(LongConsumer consumer) {
831 if (consumer == null) throw new NullPointerException();
832 long i = index, f = fence;
833 if (i < f) {
834 index = f;
835 long o = origin, b = bound;
836 ThreadLocalRandom rng = ThreadLocalRandom.current();
837 do {
838 consumer.accept(rng.internalNextLong(o, b));
839 } while (++i < f);
840 }
841 }
842
843 }
844
845 /**
846 * Spliterator for double streams.
847 */
848 static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
849 long index;
850 final long fence;
851 final double origin;
852 final double bound;
853 RandomDoublesSpliterator(long index, long fence,
854 double origin, double bound) {
855 this.index = index; this.fence = fence;
856 this.origin = origin; this.bound = bound;
857 }
858
859 public RandomDoublesSpliterator trySplit() {
860 long i = index, m = (i + fence) >>> 1;
861 return (m <= i) ? null :
862 new RandomDoublesSpliterator(i, index = m, origin, bound);
863 }
864
865 public long estimateSize() {
866 return fence - index;
867 }
868
869 public int characteristics() {
870 return (Spliterator.SIZED | Spliterator.SUBSIZED |
871 Spliterator.NONNULL | Spliterator.IMMUTABLE);
872 }
873
874 public boolean tryAdvance(DoubleConsumer consumer) {
875 if (consumer == null) throw new NullPointerException();
876 long i = index, f = fence;
877 if (i < f) {
878 consumer.accept(ThreadLocalRandom.current().internalNextDouble(origin, bound));
879 index = i + 1;
880 return true;
881 }
882 return false;
883 }
884
885 public void forEachRemaining(DoubleConsumer consumer) {
886 if (consumer == null) throw new NullPointerException();
887 long i = index, f = fence;
888 if (i < f) {
889 index = f;
890 double o = origin, b = bound;
891 ThreadLocalRandom rng = ThreadLocalRandom.current();
892 do {
893 consumer.accept(rng.internalNextDouble(o, b));
894 } while (++i < f);
895 }
896 }
897 }
898
899
900 // Within-package utilities
901
902 /*
903 * Descriptions of the usages of the methods below can be found in
904 * the classes that use them. Briefly, a thread's "probe" value is
905 * a non-zero hash code that (probably) does not collide with
906 * other existing threads with respect to any power of two
907 * collision space. When it does collide, it is pseudo-randomly
908 * adjusted (using a Marsaglia XorShift). The nextSecondarySeed
909 * method is used in the same contexts as ThreadLocalRandom, but
910 * only for transient usages such as random adaptive spin/block
911 * sequences for which a cheap RNG suffices and for which it could
912 * in principle disrupt user-visible statistical properties of the
913 * main ThreadLocalRandom if we were to use it.
914 *
915 * Note: Because of package-protection issues, versions of some
916 * these methods also appear in some subpackage classes.
917 */
918
919 /**
920 * Returns the probe value for the current thread without forcing
921 * initialization. Note that invoking ThreadLocalRandom.current()
922 * can be used to force initialization on zero return.
923 */
924 static final int getProbe() {
925 return UNSAFE.getInt(Thread.currentThread(), PROBE);
926 }
927
928 /**
929 * Pseudo-randomly advances and records the given probe value for the
930 * given thread.
931 */
932 static final int advanceProbe(int probe) {
933 probe ^= probe << 13; // xorshift
934 probe ^= probe >>> 17;
935 probe ^= probe << 5;
936 UNSAFE.putInt(Thread.currentThread(), PROBE, probe);
937 return probe;
938 }
939
940 /**
941 * Returns the pseudo-randomly initialized or updated secondary seed.
942 */
943 static final int nextSecondarySeed() {
944 int r;
945 Thread t = Thread.currentThread();
946 if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
947 r ^= r << 13; // xorshift
948 r ^= r >>> 17;
949 r ^= r << 5;
950 }
951 else {
952 localInit();
953 if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
954 r = 1; // avoid zero
955 }
956 UNSAFE.putInt(t, SECONDARY, r);
957 return r;
958 }
959
960 // Serialization support
961
962 private static final long serialVersionUID = -5851777807851030925L;
963
964 /**
965 * @serialField rnd long
966 * seed for random computations
967 * @serialField initialized boolean
968 * always true
969 */
970 private static final ObjectStreamField[] serialPersistentFields = {
971 new ObjectStreamField("rnd", long.class),
972 new ObjectStreamField("initialized", boolean.class),
973 };
974
975 /**
976 * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
977 * @param s the stream
978 * @throws java.io.IOException if an I/O error occurs
979 */
980 private void writeObject(java.io.ObjectOutputStream s)
981 throws java.io.IOException {
982
983 java.io.ObjectOutputStream.PutField fields = s.putFields();
984 fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
985 fields.put("initialized", true);
986 s.writeFields();
987 }
988
989 /**
990 * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
991 * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
992 */
993 private Object readResolve() {
994 return current();
995 }
996
997 // Unsafe mechanics
998 private static final sun.misc.Unsafe UNSAFE;
999 private static final long SEED;
1000 private static final long PROBE;
1001 private static final long SECONDARY;
1002 static {
1003 try {
1004 UNSAFE = sun.misc.Unsafe.getUnsafe();
1005 Class<?> tk = Thread.class;
1006 SEED = UNSAFE.objectFieldOffset
1007 (tk.getDeclaredField("threadLocalRandomSeed"));
1008 PROBE = UNSAFE.objectFieldOffset
1009 (tk.getDeclaredField("threadLocalRandomProbe"));
1010 SECONDARY = UNSAFE.objectFieldOffset
1011 (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
1012 } catch (Exception e) {
1013 throw new Error(e);
1014 }
1015 }
1016 }