ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.22
Committed: Fri Aug 23 23:02:59 2013 UTC (10 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.21: +4 -28 lines
Log Message:
Avoid VM startup problems

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