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