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; |
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. Additionally, instances do not |
48 |
+ |
* use a cryptographically random seed unless the {@linkplain |
49 |
+ |
* System#getProperty system property} {@code |
50 |
+ |
* java.util.secureRandomSeed} is set to {@code true}. |
51 |
+ |
* |
52 |
|
* @since 1.7 |
53 |
|
* @author Doug Lea |
54 |
|
*/ |
105 |
|
/** |
106 |
|
* The next seed for default constructors. |
107 |
|
*/ |
108 |
< |
private static final AtomicLong seedGenerator = |
109 |
< |
new AtomicLong(mix64(System.currentTimeMillis()) ^ |
110 |
< |
mix64(System.nanoTime())); |
108 |
> |
private static final AtomicLong seeder = new AtomicLong(initialSeed()); |
109 |
> |
|
110 |
> |
private static long initialSeed() { // same as SplittableRandom |
111 |
> |
try { // ignore exceptions in accessing/parsing properties |
112 |
> |
String pp = System.getProperty |
113 |
> |
("java.util.secureRandomSeed"); |
114 |
> |
if (pp != null && pp.equalsIgnoreCase("true")) { |
115 |
> |
byte[] seedBytes = java.security.SecureRandom.getSeed(8); |
116 |
> |
long s = (long)(seedBytes[0]) & 0xffL; |
117 |
> |
for (int i = 1; i < 8; ++i) |
118 |
> |
s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); |
119 |
> |
return s; |
120 |
> |
} |
121 |
> |
} catch (Exception ignore) { |
122 |
> |
} |
123 |
> |
int hh = 0; // hashed host address |
124 |
> |
try { |
125 |
> |
hh = InetAddress.getLocalHost().hashCode(); |
126 |
> |
} catch (Exception ignore) { |
127 |
> |
} |
128 |
> |
return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^ |
129 |
> |
mix64(System.nanoTime())); |
130 |
> |
} |
131 |
|
|
132 |
|
/** |
133 |
|
* The seed increment |
140 |
|
private static final int PROBE_INCREMENT = 0x9e3779b9; |
141 |
|
|
142 |
|
/** |
143 |
< |
* The increment of seedGenerator per new instance |
143 |
> |
* The increment of seeder per new instance |
144 |
|
*/ |
145 |
|
private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL; |
146 |
|
|
187 |
|
static final void localInit() { |
188 |
|
int p = probeGenerator.addAndGet(PROBE_INCREMENT); |
189 |
|
int probe = (p == 0) ? 1 : p; // skip 0 |
190 |
< |
long seed = mix64(seedGenerator.getAndAdd(SEEDER_INCREMENT)); |
190 |
> |
long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT)); |
191 |
|
Thread t = Thread.currentThread(); |
192 |
|
UNSAFE.putLong(t, SEED, seed); |
193 |
|
UNSAFE.putInt(t, PROBE, probe); |
322 |
|
* Returns a pseudorandom {@code int} value between zero (inclusive) |
323 |
|
* and the specified bound (exclusive). |
324 |
|
* |
325 |
< |
* @param bound the bound on the random number to be returned. Must be |
297 |
< |
* positive. |
325 |
> |
* @param bound the upper bound (exclusive). Must be positive. |
326 |
|
* @return a pseudorandom {@code int} value between zero |
327 |
|
* (inclusive) and the bound (exclusive) |
328 |
|
* @throws IllegalArgumentException if {@code bound} is not positive |
373 |
|
* Returns a pseudorandom {@code long} value between zero (inclusive) |
374 |
|
* and the specified bound (exclusive). |
375 |
|
* |
376 |
< |
* @param bound the bound on the random number to be returned. Must be |
349 |
< |
* positive. |
376 |
> |
* @param bound the upper bound (exclusive). Must be positive. |
377 |
|
* @return a pseudorandom {@code long} value between zero |
378 |
|
* (inclusive) and the bound (exclusive) |
379 |
|
* @throws IllegalArgumentException if {@code bound} is not positive |
416 |
|
* (inclusive) and one (exclusive). |
417 |
|
* |
418 |
|
* @return a pseudorandom {@code double} value between zero |
419 |
< |
* (inclusive) and one (exclusive) |
419 |
> |
* (inclusive) and one (exclusive) |
420 |
|
*/ |
421 |
|
public double nextDouble() { |
422 |
|
return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT; |
426 |
|
* Returns a pseudorandom {@code double} value between 0.0 |
427 |
|
* (inclusive) and the specified bound (exclusive). |
428 |
|
* |
429 |
< |
* @param bound the bound on the random number to be returned. Must be |
403 |
< |
* positive. |
429 |
> |
* @param bound the upper bound (exclusive). Must be positive. |
430 |
|
* @return a pseudorandom {@code double} value between zero |
431 |
|
* (inclusive) and the bound (exclusive) |
432 |
|
* @throws IllegalArgumentException if {@code bound} is not positive |
444 |
|
* origin (inclusive) and bound (exclusive). |
445 |
|
* |
446 |
|
* @param origin the least value returned |
447 |
< |
* @param bound the upper bound |
447 |
> |
* @param bound the upper bound (exclusive) |
448 |
|
* @return a pseudorandom {@code double} value between the origin |
449 |
|
* (inclusive) and the bound (exclusive) |
450 |
|
* @throws IllegalArgumentException if {@code origin} is greater than |
470 |
|
* (inclusive) and one (exclusive). |
471 |
|
* |
472 |
|
* @return a pseudorandom {@code float} value between zero |
473 |
< |
* (inclusive) and one (exclusive) |
473 |
> |
* (inclusive) and one (exclusive) |
474 |
|
*/ |
475 |
|
public float nextFloat() { |
476 |
|
return (mix32(nextSeed()) >>> 8) * FLOAT_UNIT; |
494 |
|
return v1 * multiplier; |
495 |
|
} |
496 |
|
|
471 |
– |
@Override |
472 |
– |
public DoubleStream gaussians() { |
473 |
– |
return DoubleStream.generate(() -> current().nextGaussian()); |
474 |
– |
} |
475 |
– |
|
497 |
|
// stream methods, coded in a way intended to better isolate for |
498 |
|
// maintenance purposes the small differences across forms. |
499 |
|
|
505 |
|
* @return a stream of pseudorandom {@code int} values |
506 |
|
* @throws IllegalArgumentException if {@code streamSize} is |
507 |
|
* less than zero |
508 |
+ |
* @since 1.8 |
509 |
|
*/ |
510 |
|
public IntStream ints(long streamSize) { |
511 |
|
if (streamSize < 0L) |
524 |
|
* ints(Long.MAX_VALUE)}. |
525 |
|
* |
526 |
|
* @return a stream of pseudorandom {@code int} values |
527 |
+ |
* @since 1.8 |
528 |
|
*/ |
529 |
|
public IntStream ints() { |
530 |
|
return StreamSupport.intStream |
534 |
|
} |
535 |
|
|
536 |
|
/** |
537 |
< |
* Returns a stream producing the given {@code streamSize} number of |
538 |
< |
* pseudorandom {@code int} values, each conforming to the given |
539 |
< |
* origin and bound. |
537 |
> |
* Returns a stream producing the given {@code streamSize} number |
538 |
> |
* of pseudorandom {@code int} values, each conforming to the given |
539 |
> |
* origin (inclusive) and bound (exclusive). |
540 |
|
* |
541 |
|
* @param streamSize the number of values to generate |
542 |
< |
* @param randomNumberOrigin the origin of each random value |
543 |
< |
* @param randomNumberBound the bound of each random value |
542 |
> |
* @param randomNumberOrigin the origin (inclusive) of each random value |
543 |
> |
* @param randomNumberBound the bound (exclusive) of each random value |
544 |
|
* @return a stream of pseudorandom {@code int} values, |
545 |
< |
* each with the given origin and bound |
545 |
> |
* each with the given origin (inclusive) and bound (exclusive) |
546 |
|
* @throws IllegalArgumentException if {@code streamSize} is |
547 |
|
* less than zero, or {@code randomNumberOrigin} |
548 |
|
* is greater than or equal to {@code randomNumberBound} |
549 |
+ |
* @since 1.8 |
550 |
|
*/ |
551 |
|
public IntStream ints(long streamSize, int randomNumberOrigin, |
552 |
|
int randomNumberBound) { |
562 |
|
|
563 |
|
/** |
564 |
|
* Returns an effectively unlimited stream of pseudorandom {@code |
565 |
< |
* int} values, each conforming to the given origin and bound. |
565 |
> |
* int} values, each conforming to the given origin (inclusive) and bound |
566 |
> |
* (exclusive). |
567 |
|
* |
568 |
|
* @implNote This method is implemented to be equivalent to {@code |
569 |
|
* ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. |
570 |
|
* |
571 |
< |
* @param randomNumberOrigin the origin of each random value |
572 |
< |
* @param randomNumberBound the bound of each random value |
571 |
> |
* @param randomNumberOrigin the origin (inclusive) of each random value |
572 |
> |
* @param randomNumberBound the bound (exclusive) of each random value |
573 |
|
* @return a stream of pseudorandom {@code int} values, |
574 |
< |
* each with the given origin and bound |
574 |
> |
* each with the given origin (inclusive) and bound (exclusive) |
575 |
|
* @throws IllegalArgumentException if {@code randomNumberOrigin} |
576 |
|
* is greater than or equal to {@code randomNumberBound} |
577 |
+ |
* @since 1.8 |
578 |
|
*/ |
579 |
|
public IntStream ints(int randomNumberOrigin, int randomNumberBound) { |
580 |
|
if (randomNumberOrigin >= randomNumberBound) |
593 |
|
* @return a stream of pseudorandom {@code long} values |
594 |
|
* @throws IllegalArgumentException if {@code streamSize} is |
595 |
|
* less than zero |
596 |
+ |
* @since 1.8 |
597 |
|
*/ |
598 |
|
public LongStream longs(long streamSize) { |
599 |
|
if (streamSize < 0L) |
612 |
|
* longs(Long.MAX_VALUE)}. |
613 |
|
* |
614 |
|
* @return a stream of pseudorandom {@code long} values |
615 |
+ |
* @since 1.8 |
616 |
|
*/ |
617 |
|
public LongStream longs() { |
618 |
|
return StreamSupport.longStream |
623 |
|
|
624 |
|
/** |
625 |
|
* Returns a stream producing the given {@code streamSize} number of |
626 |
< |
* pseudorandom {@code long} values, each conforming to the |
627 |
< |
* given origin and bound. |
626 |
> |
* pseudorandom {@code long}, each conforming to the given origin |
627 |
> |
* (inclusive) and bound (exclusive). |
628 |
|
* |
629 |
|
* @param streamSize the number of values to generate |
630 |
< |
* @param randomNumberOrigin the origin of each random value |
631 |
< |
* @param randomNumberBound the bound of each random value |
630 |
> |
* @param randomNumberOrigin the origin (inclusive) of each random value |
631 |
> |
* @param randomNumberBound the bound (exclusive) of each random value |
632 |
|
* @return a stream of pseudorandom {@code long} values, |
633 |
< |
* each with the given origin and bound |
633 |
> |
* each with the given origin (inclusive) and bound (exclusive) |
634 |
|
* @throws IllegalArgumentException if {@code streamSize} is |
635 |
|
* less than zero, or {@code randomNumberOrigin} |
636 |
|
* is greater than or equal to {@code randomNumberBound} |
637 |
+ |
* @since 1.8 |
638 |
|
*/ |
639 |
|
public LongStream longs(long streamSize, long randomNumberOrigin, |
640 |
|
long randomNumberBound) { |
650 |
|
|
651 |
|
/** |
652 |
|
* Returns an effectively unlimited stream of pseudorandom {@code |
653 |
< |
* long} values, each conforming to the given origin and bound. |
653 |
> |
* long} values, each conforming to the given origin (inclusive) and bound |
654 |
> |
* (exclusive). |
655 |
|
* |
656 |
|
* @implNote This method is implemented to be equivalent to {@code |
657 |
|
* longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. |
658 |
|
* |
659 |
< |
* @param randomNumberOrigin the origin of each random value |
660 |
< |
* @param randomNumberBound the bound of each random value |
659 |
> |
* @param randomNumberOrigin the origin (inclusive) of each random value |
660 |
> |
* @param randomNumberBound the bound (exclusive) of each random value |
661 |
|
* @return a stream of pseudorandom {@code long} values, |
662 |
< |
* each with the given origin and bound |
662 |
> |
* each with the given origin (inclusive) and bound (exclusive) |
663 |
|
* @throws IllegalArgumentException if {@code randomNumberOrigin} |
664 |
|
* is greater than or equal to {@code randomNumberBound} |
665 |
+ |
* @since 1.8 |
666 |
|
*/ |
667 |
|
public LongStream longs(long randomNumberOrigin, long randomNumberBound) { |
668 |
|
if (randomNumberOrigin >= randomNumberBound) |
682 |
|
* @return a stream of {@code double} values |
683 |
|
* @throws IllegalArgumentException if {@code streamSize} is |
684 |
|
* less than zero |
685 |
+ |
* @since 1.8 |
686 |
|
*/ |
687 |
|
public DoubleStream doubles(long streamSize) { |
688 |
|
if (streamSize < 0L) |
702 |
|
* doubles(Long.MAX_VALUE)}. |
703 |
|
* |
704 |
|
* @return a stream of pseudorandom {@code double} values |
705 |
+ |
* @since 1.8 |
706 |
|
*/ |
707 |
|
public DoubleStream doubles() { |
708 |
|
return StreamSupport.doubleStream |
713 |
|
|
714 |
|
/** |
715 |
|
* Returns a stream producing the given {@code streamSize} number of |
716 |
< |
* pseudorandom {@code double} values, each conforming to the |
717 |
< |
* given origin and bound. |
716 |
> |
* pseudorandom {@code double} values, each conforming to the given origin |
717 |
> |
* (inclusive) and bound (exclusive). |
718 |
|
* |
719 |
|
* @param streamSize the number of values to generate |
720 |
< |
* @param randomNumberOrigin the origin of each random value |
721 |
< |
* @param randomNumberBound the bound of each random value |
720 |
> |
* @param randomNumberOrigin the origin (inclusive) of each random value |
721 |
> |
* @param randomNumberBound the bound (exclusive) of each random value |
722 |
|
* @return a stream of pseudorandom {@code double} values, |
723 |
< |
* each with the given origin and bound |
723 |
> |
* each with the given origin (inclusive) and bound (exclusive) |
724 |
|
* @throws IllegalArgumentException if {@code streamSize} is |
725 |
< |
* less than zero |
725 |
> |
* less than zero |
726 |
|
* @throws IllegalArgumentException if {@code randomNumberOrigin} |
727 |
|
* is greater than or equal to {@code randomNumberBound} |
728 |
+ |
* @since 1.8 |
729 |
|
*/ |
730 |
|
public DoubleStream doubles(long streamSize, double randomNumberOrigin, |
731 |
|
double randomNumberBound) { |
741 |
|
|
742 |
|
/** |
743 |
|
* Returns an effectively unlimited stream of pseudorandom {@code |
744 |
< |
* double} values, each conforming to the given origin and bound. |
744 |
> |
* double} values, each conforming to the given origin (inclusive) and bound |
745 |
> |
* (exclusive). |
746 |
|
* |
747 |
|
* @implNote This method is implemented to be equivalent to {@code |
748 |
|
* doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. |
749 |
|
* |
750 |
< |
* @param randomNumberOrigin the origin of each random value |
751 |
< |
* @param randomNumberBound the bound of each random value |
750 |
> |
* @param randomNumberOrigin the origin (inclusive) of each random value |
751 |
> |
* @param randomNumberBound the bound (exclusive) of each random value |
752 |
|
* @return a stream of pseudorandom {@code double} values, |
753 |
< |
* each with the given origin and bound |
753 |
> |
* each with the given origin (inclusive) and bound (exclusive) |
754 |
|
* @throws IllegalArgumentException if {@code randomNumberOrigin} |
755 |
|
* is greater than or equal to {@code randomNumberBound} |
756 |
+ |
* @since 1.8 |
757 |
|
*/ |
758 |
|
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) { |
759 |
|
if (!(randomNumberOrigin < randomNumberBound)) |