ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java (file contents):
Revision 1.63 by jsr166, Sun Sep 8 01:11:04 2019 UTC vs.
Revision 1.64 by dl, Fri Mar 18 16:01:42 2022 UTC

# Line 2 | Line 2
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4   * http://creativecommons.org/publicdomain/zero/1.0/
5 + * Additional modifications by Guy Steele in 2019 to refactor the code
6 + * and to implement the {@link RandomGenerator} interface.
7   */
8  
9   package java.util.concurrent;
10  
11   import java.io.ObjectStreamField;
12 + import java.math.BigInteger;
13   import java.security.AccessControlContext;
14 + import java.util.Map;
15   import java.util.Random;
16   import java.util.Spliterator;
17   import java.util.concurrent.atomic.AtomicInteger;
18   import java.util.concurrent.atomic.AtomicLong;
19 < import java.util.function.DoubleConsumer;
16 < import java.util.function.IntConsumer;
17 < import java.util.function.LongConsumer;
19 > import java.util.random.RandomGenerator;
20   import java.util.stream.DoubleStream;
21   import java.util.stream.IntStream;
22   import java.util.stream.LongStream;
23 < import java.util.stream.StreamSupport;
23 > import jdk.internal.util.random.RandomSupport;
24 > import jdk.internal.util.random.RandomSupport.*;
25   import jdk.internal.misc.Unsafe;
26   import jdk.internal.misc.VM;
27  
28   /**
29 < * A random number generator isolated to the current thread.  Like the
30 < * global {@link java.util.Random} generator used by the {@link
31 < * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
29 > * A random number generator (with period 2<sup>64</sup>) isolated
30 > * to the current thread.  Like the global {@link java.util.Random}
31 > * generator used by the {@link java.lang.Math} class,
32 > * a {@code ThreadLocalRandom} is initialized
33   * with an internally generated seed that may not otherwise be
34   * modified. When applicable, use of {@code ThreadLocalRandom} rather
35   * than shared {@code Random} objects in concurrent programs will
# Line 53 | Line 57 | import jdk.internal.misc.VM;
57   * @since 1.7
58   * @author Doug Lea
59   */
60 +
61 + @RandomGeneratorProperties(
62 +        name = "ThreadLocalRandom",
63 +        i = 64, j = 0, k = 0,
64 +        equidistribution = 1
65 + )
66   public class ThreadLocalRandom extends Random {
67      /*
68       * This class implements the java.util.Random API (and subclasses
69 <     * Random) using a single static instance that accesses random
70 <     * number state held in class Thread (primarily, field
69 >     * Random) using a single static instance that accesses 64 bits of
70 >     * random number state held in class java.lang.Thread (field
71       * threadLocalRandomSeed). In doing so, it also provides a home
72       * for managing package-private utilities that rely on exactly the
73       * same state as needed to maintain the ThreadLocalRandom
# Line 76 | Line 86 | public class ThreadLocalRandom extends R
86       * Even though this class subclasses java.util.Random, it uses the
87       * same basic algorithm as java.util.SplittableRandom.  (See its
88       * internal documentation for explanations, which are not repeated
89 <     * here.)  Because ThreadLocalRandoms are not splittable
90 <     * though, we use only a single 64bit gamma.
89 >     * here.)  Note that ThreadLocalRandom is not a "splittable" generator
90 >     * (it does not support the split method), but it behaves as if
91 >     * one instance of the SplittableRandom algorithm had been
92 >     * created for each thread, each with a distinct gamma parameter
93 >     * (calculated from the thread id).
94       *
95       * Because this class is in a different package than class Thread,
96       * field access methods use Unsafe to bypass access control rules.
# Line 94 | Line 107 | public class ThreadLocalRandom extends R
107       * SplittableRandom, that were in part derived from a previous
108       * version of this class.
109       *
110 <     * The nextLocalGaussian ThreadLocal supports the very rarely used
111 <     * nextGaussian method by providing a holder for the second of a
112 <     * pair of them. As is true for the base class version of this
113 <     * method, this time/space tradeoff is probably never worthwhile,
101 <     * but we provide identical statistical properties.
110 >     * This implementation of ThreadLocalRandom overrides the
111 >     * definition of the nextGaussian() method in the class Random,
112 >     * and instead uses the ziggurat-based algorithm that is the
113 >     * default for the RandomGenerator interface.
114       */
115  
104    private static long mix64(long z) {
105        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
106        z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
107        return z ^ (z >>> 33);
108    }
109
116      private static int mix32(long z) {
117          z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
118          return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
# Line 133 | Line 139 | public class ThreadLocalRandom extends R
139      static final void localInit() {
140          int p = probeGenerator.addAndGet(PROBE_INCREMENT);
141          int probe = (p == 0) ? 1 : p; // skip 0
142 <        long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
142 >        long seed = RandomSupport.mixMurmur64(seeder.getAndAdd(SEEDER_INCREMENT));
143          Thread t = Thread.currentThread();
144          U.putLong(t, SEED, seed);
145          U.putInt(t, PROBE, probe);
146      }
147  
148      /**
149 <     * Returns the current thread's {@code ThreadLocalRandom}.
149 >     * Returns the current thread's {@code ThreadLocalRandom} object.
150 >     * Methods of this object should be called only by the current thread,
151 >     * not by other threads.
152       *
153       * @return the current thread's {@code ThreadLocalRandom}
154       */
# Line 162 | Line 170 | public class ThreadLocalRandom extends R
170              throw new UnsupportedOperationException();
171      }
172  
173 +    /**
174 +     * Update the thread local seed value by adding to it the sum
175 +     * of {@code GOLDEN_GAMMA} (an odd value) and twice the thread id.
176 +     * This sum is always odd (to guarantee that the generator
177 +     * has maximum period) and is different for different threads.
178 +     * Because thread id values are allocated consecutively starting
179 +     * from 0, the high 32 bits of this sum will be the same as the
180 +     * high 32 bits of {@code GOLDEN_GAMMA} unless an extremely large
181 +     * number of threads have been created, and so the overall
182 +     * value added to the thread local seed value will have at least
183 +     * fourteen 01 and 10 transitions (see the documentation for the
184 +     * method {@code mixGamma} in class {@code SplittableRandom}),
185 +     * which should provide adequate statistical quality for
186 +     * applications likely to use {@code ThreadLocalRandom}.
187 +     */
188      final long nextSeed() {
189          Thread t; long r; // read and update per-thread seed
190          U.putLong(t = Thread.currentThread(), SEED,
191 <                  r = U.getLong(t, SEED) + GAMMA);
191 >                  r = U.getLong(t, SEED) + (t.getId() << 1) + GOLDEN_GAMMA);
192          return r;
193      }
194  
# Line 182 | Line 205 | public class ThreadLocalRandom extends R
205          return nextInt() >>> (32 - bits);
206      }
207  
185    /**
186     * The form of nextLong used by LongStream Spliterators.  If
187     * origin is greater than bound, acts as unbounded form of
188     * nextLong, else as bounded form.
189     *
190     * @param origin the least value, unless greater than bound
191     * @param bound the upper bound (exclusive), must not equal origin
192     * @return a pseudorandom value
193     */
194    final long internalNextLong(long origin, long bound) {
195        long r = mix64(nextSeed());
196        if (origin < bound) {
197            long n = bound - origin, m = n - 1;
198            if ((n & m) == 0L)  // power of two
199                r = (r & m) + origin;
200            else if (n > 0L) {  // reject over-represented candidates
201                for (long u = r >>> 1;            // ensure nonnegative
202                     u + m - (r = u % n) < 0L;    // rejection check
203                     u = mix64(nextSeed()) >>> 1) // retry
204                    ;
205                r += origin;
206            }
207            else {              // range not representable as long
208                while (r < origin || r >= bound)
209                    r = mix64(nextSeed());
210            }
211        }
212        return r;
213    }
214
215    /**
216     * The form of nextInt used by IntStream Spliterators.
217     * Exactly the same as long version, except for types.
218     *
219     * @param origin the least value, unless greater than bound
220     * @param bound the upper bound (exclusive), must not equal origin
221     * @return a pseudorandom value
222     */
223    final int internalNextInt(int origin, int bound) {
224        int r = mix32(nextSeed());
225        if (origin < bound) {
226            int n = bound - origin, m = n - 1;
227            if ((n & m) == 0)
228                r = (r & m) + origin;
229            else if (n > 0) {
230                for (int u = r >>> 1;
231                     u + m - (r = u % n) < 0;
232                     u = mix32(nextSeed()) >>> 1)
233                    ;
234                r += origin;
235            }
236            else {
237                while (r < origin || r >= bound)
238                    r = mix32(nextSeed());
239            }
240        }
241        return r;
242    }
243
244    /**
245     * The form of nextDouble used by DoubleStream Spliterators.
246     *
247     * @param origin the least value, unless greater than bound
248     * @param bound the upper bound (exclusive), must not equal origin
249     * @return a pseudorandom value
250     */
251    final double internalNextDouble(double origin, double bound) {
252        double r = (nextLong() >>> 11) * DOUBLE_UNIT;
253        if (origin < bound) {
254            r = r * (bound - origin) + origin;
255            if (r >= bound) // correct for rounding
256                r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
257        }
258        return r;
259    }
260
261    /**
262     * Returns a pseudorandom {@code int} value.
263     *
264     * @return a pseudorandom {@code int} value
265     */
266    public int nextInt() {
267        return mix32(nextSeed());
268    }
269
270    /**
271     * Returns a pseudorandom {@code int} value between zero (inclusive)
272     * and the specified bound (exclusive).
273     *
274     * @param bound the upper bound (exclusive).  Must be positive.
275     * @return a pseudorandom {@code int} value between zero
276     *         (inclusive) and the bound (exclusive)
277     * @throws IllegalArgumentException if {@code bound} is not positive
278     */
279    public int nextInt(int bound) {
280        if (bound <= 0)
281            throw new IllegalArgumentException(BAD_BOUND);
282        int r = mix32(nextSeed());
283        int m = bound - 1;
284        if ((bound & m) == 0) // power of two
285            r &= m;
286        else { // reject over-represented candidates
287            for (int u = r >>> 1;
288                 u + m - (r = u % bound) < 0;
289                 u = mix32(nextSeed()) >>> 1)
290                ;
291        }
292        return r;
293    }
294
295    /**
296     * Returns a pseudorandom {@code int} value between the specified
297     * origin (inclusive) and the specified bound (exclusive).
298     *
299     * @param origin the least value returned
300     * @param bound the upper bound (exclusive)
301     * @return a pseudorandom {@code int} value between the origin
302     *         (inclusive) and the bound (exclusive)
303     * @throws IllegalArgumentException if {@code origin} is greater than
304     *         or equal to {@code bound}
305     */
306    public int nextInt(int origin, int bound) {
307        if (origin >= bound)
308            throw new IllegalArgumentException(BAD_RANGE);
309        return internalNextInt(origin, bound);
310    }
311
312    /**
313     * Returns a pseudorandom {@code long} value.
314     *
315     * @return a pseudorandom {@code long} value
316     */
317    public long nextLong() {
318        return mix64(nextSeed());
319    }
320
321    /**
322     * Returns a pseudorandom {@code long} value between zero (inclusive)
323     * and the specified bound (exclusive).
324     *
325     * @param bound the upper bound (exclusive).  Must be positive.
326     * @return a pseudorandom {@code long} value between zero
327     *         (inclusive) and the bound (exclusive)
328     * @throws IllegalArgumentException if {@code bound} is not positive
329     */
330    public long nextLong(long bound) {
331        if (bound <= 0)
332            throw new IllegalArgumentException(BAD_BOUND);
333        long r = mix64(nextSeed());
334        long m = bound - 1;
335        if ((bound & m) == 0L) // power of two
336            r &= m;
337        else { // reject over-represented candidates
338            for (long u = r >>> 1;
339                 u + m - (r = u % bound) < 0L;
340                 u = mix64(nextSeed()) >>> 1)
341                ;
342        }
343        return r;
344    }
345
346    /**
347     * Returns a pseudorandom {@code long} value between the specified
348     * origin (inclusive) and the specified bound (exclusive).
349     *
350     * @param origin the least value returned
351     * @param bound the upper bound (exclusive)
352     * @return a pseudorandom {@code long} value between the origin
353     *         (inclusive) and the bound (exclusive)
354     * @throws IllegalArgumentException if {@code origin} is greater than
355     *         or equal to {@code bound}
356     */
357    public long nextLong(long origin, long bound) {
358        if (origin >= bound)
359            throw new IllegalArgumentException(BAD_RANGE);
360        return internalNextLong(origin, bound);
361    }
362
363    /**
364     * Returns a pseudorandom {@code double} value between zero
365     * (inclusive) and one (exclusive).
366     *
367     * @return a pseudorandom {@code double} value between zero
368     *         (inclusive) and one (exclusive)
369     */
370    public double nextDouble() {
371        return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
372    }
373
374    /**
375     * Returns a pseudorandom {@code double} value between 0.0
376     * (inclusive) and the specified bound (exclusive).
377     *
378     * @param bound the upper bound (exclusive).  Must be positive.
379     * @return a pseudorandom {@code double} value between zero
380     *         (inclusive) and the bound (exclusive)
381     * @throws IllegalArgumentException if {@code bound} is not positive
382     */
383    public double nextDouble(double bound) {
384        if (!(bound > 0.0))
385            throw new IllegalArgumentException(BAD_BOUND);
386        double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
387        return (result < bound) ? result : // correct for rounding
388            Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
389    }
390
391    /**
392     * Returns a pseudorandom {@code double} value between the specified
393     * origin (inclusive) and bound (exclusive).
394     *
395     * @param origin the least value returned
396     * @param bound the upper bound (exclusive)
397     * @return a pseudorandom {@code double} value between the origin
398     *         (inclusive) and the bound (exclusive)
399     * @throws IllegalArgumentException if {@code origin} is greater than
400     *         or equal to {@code bound}
401     */
402    public double nextDouble(double origin, double bound) {
403        if (!(origin < bound))
404            throw new IllegalArgumentException(BAD_RANGE);
405        return internalNextDouble(origin, bound);
406    }
407
408    /**
409     * Returns a pseudorandom {@code boolean} value.
410     *
411     * @return a pseudorandom {@code boolean} value
412     */
413    public boolean nextBoolean() {
414        return mix32(nextSeed()) < 0;
415    }
416
417    /**
418     * Returns a pseudorandom {@code float} value between zero
419     * (inclusive) and one (exclusive).
420     *
421     * @return a pseudorandom {@code float} value between zero
422     *         (inclusive) and one (exclusive)
423     */
424    public float nextFloat() {
425        return (mix32(nextSeed()) >>> 8) * FLOAT_UNIT;
426    }
427
428    public double nextGaussian() {
429        // Use nextLocalGaussian instead of nextGaussian field
430        Double d = nextLocalGaussian.get();
431        if (d != null) {
432            nextLocalGaussian.set(null);
433            return d.doubleValue();
434        }
435        double v1, v2, s;
436        do {
437            v1 = 2 * nextDouble() - 1; // between -1 and 1
438            v2 = 2 * nextDouble() - 1; // between -1 and 1
439            s = v1 * v1 + v2 * v2;
440        } while (s >= 1 || s == 0);
441        double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
442        nextLocalGaussian.set(Double.valueOf(v2 * multiplier));
443        return v1 * multiplier;
444    }
445
446    // stream methods, coded in a way intended to better isolate for
447    // maintenance purposes the small differences across forms.
448
449    /**
450     * Returns a stream producing the given {@code streamSize} number of
451     * pseudorandom {@code int} values.
452     *
453     * @param streamSize the number of values to generate
454     * @return a stream of pseudorandom {@code int} values
455     * @throws IllegalArgumentException if {@code streamSize} is
456     *         less than zero
457     * @since 1.8
458     */
459    public IntStream ints(long streamSize) {
460        if (streamSize < 0L)
461            throw new IllegalArgumentException(BAD_SIZE);
462        return StreamSupport.intStream
463            (new RandomIntsSpliterator
464             (0L, streamSize, Integer.MAX_VALUE, 0),
465             false);
466    }
467
468    /**
469     * Returns an effectively unlimited stream of pseudorandom {@code int}
470     * values.
471     *
472     * @implNote This method is implemented to be equivalent to {@code
473     * ints(Long.MAX_VALUE)}.
474     *
475     * @return a stream of pseudorandom {@code int} values
476     * @since 1.8
477     */
478    public IntStream ints() {
479        return StreamSupport.intStream
480            (new RandomIntsSpliterator
481             (0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
482             false);
483    }
484
485    /**
486     * Returns a stream producing the given {@code streamSize} number
487     * of pseudorandom {@code int} values, each conforming to the given
488     * origin (inclusive) and bound (exclusive).
489     *
490     * @param streamSize the number of values to generate
491     * @param randomNumberOrigin the origin (inclusive) of each random value
492     * @param randomNumberBound the bound (exclusive) of each random value
493     * @return a stream of pseudorandom {@code int} values,
494     *         each with the given origin (inclusive) and bound (exclusive)
495     * @throws IllegalArgumentException if {@code streamSize} is
496     *         less than zero, or {@code randomNumberOrigin}
497     *         is greater than or equal to {@code randomNumberBound}
498     * @since 1.8
499     */
500    public IntStream ints(long streamSize, int randomNumberOrigin,
501                          int randomNumberBound) {
502        if (streamSize < 0L)
503            throw new IllegalArgumentException(BAD_SIZE);
504        if (randomNumberOrigin >= randomNumberBound)
505            throw new IllegalArgumentException(BAD_RANGE);
506        return StreamSupport.intStream
507            (new RandomIntsSpliterator
508             (0L, streamSize, randomNumberOrigin, randomNumberBound),
509             false);
510    }
511
512    /**
513     * Returns an effectively unlimited stream of pseudorandom {@code
514     * int} values, each conforming to the given origin (inclusive) and bound
515     * (exclusive).
516     *
517     * @implNote This method is implemented to be equivalent to {@code
518     * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
519     *
520     * @param randomNumberOrigin the origin (inclusive) of each random value
521     * @param randomNumberBound the bound (exclusive) of each random value
522     * @return a stream of pseudorandom {@code int} values,
523     *         each with the given origin (inclusive) and bound (exclusive)
524     * @throws IllegalArgumentException if {@code randomNumberOrigin}
525     *         is greater than or equal to {@code randomNumberBound}
526     * @since 1.8
527     */
528    public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
529        if (randomNumberOrigin >= randomNumberBound)
530            throw new IllegalArgumentException(BAD_RANGE);
531        return StreamSupport.intStream
532            (new RandomIntsSpliterator
533             (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
534             false);
535    }
536
537    /**
538     * Returns a stream producing the given {@code streamSize} number of
539     * pseudorandom {@code long} values.
540     *
541     * @param streamSize the number of values to generate
542     * @return a stream of pseudorandom {@code long} values
543     * @throws IllegalArgumentException if {@code streamSize} is
544     *         less than zero
545     * @since 1.8
546     */
547    public LongStream longs(long streamSize) {
548        if (streamSize < 0L)
549            throw new IllegalArgumentException(BAD_SIZE);
550        return StreamSupport.longStream
551            (new RandomLongsSpliterator
552             (0L, streamSize, Long.MAX_VALUE, 0L),
553             false);
554    }
555
556    /**
557     * Returns an effectively unlimited stream of pseudorandom {@code long}
558     * values.
559     *
560     * @implNote This method is implemented to be equivalent to {@code
561     * longs(Long.MAX_VALUE)}.
562     *
563     * @return a stream of pseudorandom {@code long} values
564     * @since 1.8
565     */
566    public LongStream longs() {
567        return StreamSupport.longStream
568            (new RandomLongsSpliterator
569             (0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
570             false);
571    }
572
573    /**
574     * Returns a stream producing the given {@code streamSize} number of
575     * pseudorandom {@code long}, each conforming to the given origin
576     * (inclusive) and bound (exclusive).
577     *
578     * @param streamSize the number of values to generate
579     * @param randomNumberOrigin the origin (inclusive) of each random value
580     * @param randomNumberBound the bound (exclusive) of each random value
581     * @return a stream of pseudorandom {@code long} values,
582     *         each with the given origin (inclusive) and bound (exclusive)
583     * @throws IllegalArgumentException if {@code streamSize} is
584     *         less than zero, or {@code randomNumberOrigin}
585     *         is greater than or equal to {@code randomNumberBound}
586     * @since 1.8
587     */
588    public LongStream longs(long streamSize, long randomNumberOrigin,
589                            long randomNumberBound) {
590        if (streamSize < 0L)
591            throw new IllegalArgumentException(BAD_SIZE);
592        if (randomNumberOrigin >= randomNumberBound)
593            throw new IllegalArgumentException(BAD_RANGE);
594        return StreamSupport.longStream
595            (new RandomLongsSpliterator
596             (0L, streamSize, randomNumberOrigin, randomNumberBound),
597             false);
598    }
599
600    /**
601     * Returns an effectively unlimited stream of pseudorandom {@code
602     * long} values, each conforming to the given origin (inclusive) and bound
603     * (exclusive).
604     *
605     * @implNote This method is implemented to be equivalent to {@code
606     * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
607     *
608     * @param randomNumberOrigin the origin (inclusive) of each random value
609     * @param randomNumberBound the bound (exclusive) of each random value
610     * @return a stream of pseudorandom {@code long} values,
611     *         each with the given origin (inclusive) and bound (exclusive)
612     * @throws IllegalArgumentException if {@code randomNumberOrigin}
613     *         is greater than or equal to {@code randomNumberBound}
614     * @since 1.8
615     */
616    public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
617        if (randomNumberOrigin >= randomNumberBound)
618            throw new IllegalArgumentException(BAD_RANGE);
619        return StreamSupport.longStream
620            (new RandomLongsSpliterator
621             (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
622             false);
623    }
624
625    /**
626     * Returns a stream producing the given {@code streamSize} number of
627     * pseudorandom {@code double} values, each between zero
628     * (inclusive) and one (exclusive).
629     *
630     * @param streamSize the number of values to generate
631     * @return a stream of {@code double} values
632     * @throws IllegalArgumentException if {@code streamSize} is
633     *         less than zero
634     * @since 1.8
635     */
636    public DoubleStream doubles(long streamSize) {
637        if (streamSize < 0L)
638            throw new IllegalArgumentException(BAD_SIZE);
639        return StreamSupport.doubleStream
640            (new RandomDoublesSpliterator
641             (0L, streamSize, Double.MAX_VALUE, 0.0),
642             false);
643    }
644
645    /**
646     * Returns an effectively unlimited stream of pseudorandom {@code
647     * double} values, each between zero (inclusive) and one
648     * (exclusive).
649     *
650     * @implNote This method is implemented to be equivalent to {@code
651     * doubles(Long.MAX_VALUE)}.
652     *
653     * @return a stream of pseudorandom {@code double} values
654     * @since 1.8
655     */
656    public DoubleStream doubles() {
657        return StreamSupport.doubleStream
658            (new RandomDoublesSpliterator
659             (0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
660             false);
661    }
662
663    /**
664     * Returns a stream producing the given {@code streamSize} number of
665     * pseudorandom {@code double} values, each conforming to the given origin
666     * (inclusive) and bound (exclusive).
667     *
668     * @param streamSize the number of values to generate
669     * @param randomNumberOrigin the origin (inclusive) of each random value
670     * @param randomNumberBound the bound (exclusive) of each random value
671     * @return a stream of pseudorandom {@code double} values,
672     *         each with the given origin (inclusive) and bound (exclusive)
673     * @throws IllegalArgumentException if {@code streamSize} is
674     *         less than zero, or {@code randomNumberOrigin}
675     *         is greater than or equal to {@code randomNumberBound}
676     * @since 1.8
677     */
678    public DoubleStream doubles(long streamSize, double randomNumberOrigin,
679                                double randomNumberBound) {
680        if (streamSize < 0L)
681            throw new IllegalArgumentException(BAD_SIZE);
682        if (!(randomNumberOrigin < randomNumberBound))
683            throw new IllegalArgumentException(BAD_RANGE);
684        return StreamSupport.doubleStream
685            (new RandomDoublesSpliterator
686             (0L, streamSize, randomNumberOrigin, randomNumberBound),
687             false);
688    }
689
690    /**
691     * Returns an effectively unlimited stream of pseudorandom {@code
692     * double} values, each conforming to the given origin (inclusive) and bound
693     * (exclusive).
694     *
695     * @implNote This method is implemented to be equivalent to {@code
696     * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
697     *
698     * @param randomNumberOrigin the origin (inclusive) of each random value
699     * @param randomNumberBound the bound (exclusive) of each random value
700     * @return a stream of pseudorandom {@code double} values,
701     *         each with the given origin (inclusive) and bound (exclusive)
702     * @throws IllegalArgumentException if {@code randomNumberOrigin}
703     *         is greater than or equal to {@code randomNumberBound}
704     * @since 1.8
705     */
706    public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
707        if (!(randomNumberOrigin < randomNumberBound))
708            throw new IllegalArgumentException(BAD_RANGE);
709        return StreamSupport.doubleStream
710            (new RandomDoublesSpliterator
711             (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
712             false);
713    }
714
715    /**
716     * Spliterator for int streams.  We multiplex the four int
717     * versions into one class by treating a bound less than origin as
718     * unbounded, and also by treating "infinite" as equivalent to
719     * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
720     * approach. The long and double versions of this class are
721     * identical except for types.
722     */
723    private static final class RandomIntsSpliterator
724            implements Spliterator.OfInt {
725        long index;
726        final long fence;
727        final int origin;
728        final int bound;
729        RandomIntsSpliterator(long index, long fence,
730                              int origin, int bound) {
731            this.index = index; this.fence = fence;
732            this.origin = origin; this.bound = bound;
733        }
734
735        public RandomIntsSpliterator trySplit() {
736            long i = index, m = (i + fence) >>> 1;
737            return (m <= i) ? null :
738                new RandomIntsSpliterator(i, index = m, origin, bound);
739        }
740
741        public long estimateSize() {
742            return fence - index;
743        }
744
745        public int characteristics() {
746            return (Spliterator.SIZED | Spliterator.SUBSIZED |
747                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
748        }
749
750        public boolean tryAdvance(IntConsumer consumer) {
751            if (consumer == null) throw new NullPointerException();
752            long i = index, f = fence;
753            if (i < f) {
754                consumer.accept(ThreadLocalRandom.current().internalNextInt(origin, bound));
755                index = i + 1;
756                return true;
757            }
758            return false;
759        }
760
761        public void forEachRemaining(IntConsumer consumer) {
762            if (consumer == null) throw new NullPointerException();
763            long i = index, f = fence;
764            if (i < f) {
765                index = f;
766                int o = origin, b = bound;
767                ThreadLocalRandom rng = ThreadLocalRandom.current();
768                do {
769                    consumer.accept(rng.internalNextInt(o, b));
770                } while (++i < f);
771            }
772        }
773    }
774
775    /**
776     * Spliterator for long streams.
777     */
778    private static final class RandomLongsSpliterator
779            implements Spliterator.OfLong {
780        long index;
781        final long fence;
782        final long origin;
783        final long bound;
784        RandomLongsSpliterator(long index, long fence,
785                               long origin, long bound) {
786            this.index = index; this.fence = fence;
787            this.origin = origin; this.bound = bound;
788        }
789
790        public RandomLongsSpliterator trySplit() {
791            long i = index, m = (i + fence) >>> 1;
792            return (m <= i) ? null :
793                new RandomLongsSpliterator(i, index = m, origin, bound);
794        }
795
796        public long estimateSize() {
797            return fence - index;
798        }
799
800        public int characteristics() {
801            return (Spliterator.SIZED | Spliterator.SUBSIZED |
802                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
803        }
804
805        public boolean tryAdvance(LongConsumer consumer) {
806            if (consumer == null) throw new NullPointerException();
807            long i = index, f = fence;
808            if (i < f) {
809                consumer.accept(ThreadLocalRandom.current().internalNextLong(origin, bound));
810                index = i + 1;
811                return true;
812            }
813            return false;
814        }
815
816        public void forEachRemaining(LongConsumer consumer) {
817            if (consumer == null) throw new NullPointerException();
818            long i = index, f = fence;
819            if (i < f) {
820                index = f;
821                long o = origin, b = bound;
822                ThreadLocalRandom rng = ThreadLocalRandom.current();
823                do {
824                    consumer.accept(rng.internalNextLong(o, b));
825                } while (++i < f);
826            }
827        }
828
829    }
830
831    /**
832     * Spliterator for double streams.
833     */
834    private static final class RandomDoublesSpliterator
835            implements Spliterator.OfDouble {
836        long index;
837        final long fence;
838        final double origin;
839        final double bound;
840        RandomDoublesSpliterator(long index, long fence,
841                                 double origin, double bound) {
842            this.index = index; this.fence = fence;
843            this.origin = origin; this.bound = bound;
844        }
845
846        public RandomDoublesSpliterator trySplit() {
847            long i = index, m = (i + fence) >>> 1;
848            return (m <= i) ? null :
849                new RandomDoublesSpliterator(i, index = m, origin, bound);
850        }
851
852        public long estimateSize() {
853            return fence - index;
854        }
855
856        public int characteristics() {
857            return (Spliterator.SIZED | Spliterator.SUBSIZED |
858                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
859        }
860
861        public boolean tryAdvance(DoubleConsumer consumer) {
862            if (consumer == null) throw new NullPointerException();
863            long i = index, f = fence;
864            if (i < f) {
865                consumer.accept(ThreadLocalRandom.current().internalNextDouble(origin, bound));
866                index = i + 1;
867                return true;
868            }
869            return false;
870        }
871
872        public void forEachRemaining(DoubleConsumer consumer) {
873            if (consumer == null) throw new NullPointerException();
874            long i = index, f = fence;
875            if (i < f) {
876                index = f;
877                double o = origin, b = bound;
878                ThreadLocalRandom rng = ThreadLocalRandom.current();
879                do {
880                    consumer.accept(rng.internalNextDouble(o, b));
881                } while (++i < f);
882            }
883        }
884    }
885
886
208      // Within-package utilities
209  
210      /*
# Line 947 | Line 268 | public class ThreadLocalRandom extends R
268       * Erases ThreadLocals by nulling out Thread maps.
269       */
270      static final void eraseThreadLocals(Thread thread) {
271 <        U.putObject(thread, THREADLOCALS, null);
272 <        U.putObject(thread, INHERITABLETHREADLOCALS, null);
271 >        U.putReference(thread, THREADLOCALS, null);
272 >        U.putReference(thread, INHERITABLETHREADLOCALS, null);
273      }
274  
275      static final void setInheritedAccessControlContext(Thread thread,
276 <                                                       AccessControlContext acc) {
277 <        U.putObjectRelease(thread, INHERITEDACCESSCONTROLCONTEXT, acc);
276 >                                                       @SuppressWarnings("removal") AccessControlContext acc) {
277 >        U.putReferenceRelease(thread, INHERITEDACCESSCONTROLCONTEXT, acc);
278      }
279  
280      // Serialization support
# Line 996 | Line 317 | public class ThreadLocalRandom extends R
317      // Static initialization
318  
319      /**
320 <     * The seed increment.
320 >     * The seed increment.  This must be an odd value for the generator to
321 >     * have the maximum period (2 to the 64th power).
322 >     *
323 >     * The value 0x9e3779b97f4a7c15L is odd, and moreover consists of the
324 >     * first 64 bits of the fractional part of the golden ratio,
325 >     * which is known to generate good Weyl sequences.
326       */
327 <    private static final long GAMMA = 0x9e3779b97f4a7c15L;
327 >    private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
328  
329      /**
330       * The increment for generating probe values.
# Line 1010 | Line 336 | public class ThreadLocalRandom extends R
336       */
337      private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
338  
1013    /**
1014     * The least non-zero value returned by nextDouble(). This value
1015     * is scaled by a random value of 53 bits to produce a result.
1016     */
1017    private static final double DOUBLE_UNIT = 0x1.0p-53;  // 1.0  / (1L << 53)
1018    private static final float  FLOAT_UNIT  = 0x1.0p-24f; // 1.0f / (1 << 24)
1019
339      // IllegalArgumentException messages
340      static final String BAD_BOUND = "bound must be positive";
341      static final String BAD_RANGE = "bound must be greater than origin";
# Line 1037 | Line 356 | public class ThreadLocalRandom extends R
356      private static final long INHERITEDACCESSCONTROLCONTEXT
357          = U.objectFieldOffset(Thread.class, "inheritedAccessControlContext");
358  
1040    /** Rarely-used holder for the second of a pair of Gaussians */
1041    private static final ThreadLocal<Double> nextLocalGaussian =
1042        new ThreadLocal<>();
1043
359      /** Generates per-thread initialization/probe field */
360      private static final AtomicInteger probeGenerator = new AtomicInteger();
361  
362      /** The common ThreadLocalRandom */
363 <    static final ThreadLocalRandom instance = new ThreadLocalRandom();
363 >    private static final ThreadLocalRandom instance = new ThreadLocalRandom();
364  
365      /**
366       * The next seed for default constructors.
367       */
368      private static final AtomicLong seeder
369 <        = new AtomicLong(mix64(System.currentTimeMillis()) ^
370 <                         mix64(System.nanoTime()));
369 >        = new AtomicLong(RandomSupport.mixMurmur64(System.currentTimeMillis()) ^
370 >                         RandomSupport.mixMurmur64(System.nanoTime()));
371  
372      // at end of <clinit> to survive static initialization circularity
373      static {
# Line 1065 | Line 380 | public class ThreadLocalRandom extends R
380              seeder.set(s);
381          }
382      }
383 +
384 +    @SuppressWarnings("serial")
385 +    private static final class ThreadLocalRandomProxy extends Random {
386 +        static final Random PROXY = new ThreadLocalRandomProxy();
387 +
388 +        public int nextInt() {
389 +            return ThreadLocalRandom.current().nextInt();
390 +        }
391 +
392 +        public long nextLong() {
393 +            return ThreadLocalRandom.current().nextLong();
394 +        }
395 +    }
396 +
397 +    /**
398 +     * {@inheritDoc}
399 +     */
400 +    @Override
401 +    public boolean nextBoolean() {
402 +        return super.nextBoolean();
403 +    }
404 +
405 +    /**
406 +     * {@inheritDoc}
407 +     */
408 +    @Override
409 +    public int nextInt() {
410 +        return mix32(nextSeed());
411 +    }
412 +
413 +    /**
414 +     * {@inheritDoc}
415 +     * @throws IllegalArgumentException {@inheritDoc}
416 +     */
417 +    @Override
418 +    public int nextInt(int bound) {
419 +        return super.nextInt(bound);
420 +    }
421 +
422 +    /**
423 +     * {@inheritDoc}
424 +     * @throws IllegalArgumentException {@inheritDoc}
425 +     */
426 +    @Override
427 +    public int nextInt(int origin, int bound) {
428 +        return super.nextInt(origin, bound);
429 +    }
430 +
431 +    /**
432 +     * {@inheritDoc}
433 +     */
434 +    @Override
435 +    public long nextLong() {
436 +        return RandomSupport.mixMurmur64(nextSeed());
437 +    }
438 +
439 +    /**
440 +     * {@inheritDoc}
441 +     * @throws IllegalArgumentException {@inheritDoc}
442 +     */
443 +    @Override
444 +    public long nextLong(long bound) {
445 +        return super.nextLong(bound);
446 +    }
447 +
448 +    /**
449 +     * {@inheritDoc}
450 +     * @throws IllegalArgumentException {@inheritDoc}
451 +     */
452 +    @Override
453 +    public long nextLong(long origin, long bound) {
454 +        return super.nextLong(origin, bound);
455 +    }
456 +
457 +    /**
458 +     * {@inheritDoc}
459 +     */
460 +    @Override
461 +    public float nextFloat() {
462 +        return super.nextFloat();
463 +    }
464 +
465 +    /**
466 +     * {@inheritDoc}
467 +     * @throws IllegalArgumentException {@inheritDoc}
468 +     * @implNote {@inheritDoc}
469 +     */
470 +    @Override
471 +    public float nextFloat(float bound) {
472 +         return super.nextFloat(bound);
473 +    }
474 +
475 +    /**
476 +     * {@inheritDoc}
477 +     * @throws IllegalArgumentException {@inheritDoc}
478 +     * @implNote {@inheritDoc}
479 +     */
480 +    @Override
481 +    public float nextFloat(float origin, float bound) {
482 +        return super.nextFloat(origin, bound);
483 +    }
484 +
485 +    /**
486 +     * {@inheritDoc}
487 +     */
488 +    @Override
489 +    public double nextDouble() {
490 +        return super.nextDouble();
491 +    }
492 +
493 +    /**
494 +     * {@inheritDoc}
495 +     * @throws IllegalArgumentException {@inheritDoc}
496 +     * @implNote {@inheritDoc}
497 +     */
498 +    @Override
499 +    public double nextDouble(double bound) {
500 +        return super.nextDouble(bound);
501 +    }
502 +
503 +    /**
504 +     * {@inheritDoc}
505 +     * @throws IllegalArgumentException {@inheritDoc}
506 +     * @implNote {@inheritDoc}
507 +     */
508 +    @Override
509 +    public double nextDouble(double origin, double bound) {
510 +        return super.nextDouble(origin, bound);
511 +    }
512 +    /**
513 +     * {@inheritDoc}
514 +     * @throws IllegalArgumentException {@inheritDoc}
515 +     * @since 1.8
516 +     */
517 +    @Override
518 +    public IntStream ints(long streamSize) {
519 +        return AbstractSpliteratorGenerator.ints(ThreadLocalRandomProxy.PROXY, streamSize);
520 +    }
521 +
522 +    /**
523 +     * {@inheritDoc}
524 +     * @implNote This method is implemented to be equivalent to
525 +     *           {@code ints(Long.MAX_VALUE)}.
526 +     * @since 1.8
527 +     */
528 +    @Override
529 +    public IntStream ints() {
530 +        return AbstractSpliteratorGenerator.ints(ThreadLocalRandomProxy.PROXY);
531 +    }
532 +
533 +    /**
534 +     * {@inheritDoc}
535 +     * @throws IllegalArgumentException {@inheritDoc}
536 +     * @since 1.8
537 +     */
538 +    @Override
539 +    public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
540 +        return AbstractSpliteratorGenerator.ints(ThreadLocalRandomProxy.PROXY, streamSize, randomNumberOrigin, randomNumberBound);
541 +    }
542 +
543 +    /**
544 +     * {@inheritDoc}
545 +     * @implNote This method is implemented to be equivalent to
546 +     *           {@code ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
547 +     * @throws IllegalArgumentException {@inheritDoc}
548 +     * @since 1.8
549 +     */
550 +    @Override
551 +    public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
552 +        return AbstractSpliteratorGenerator.ints(ThreadLocalRandomProxy.PROXY, randomNumberOrigin, randomNumberBound);
553 +    }
554 +
555 +    /**
556 +     * {@inheritDoc}
557 +     * @throws IllegalArgumentException {@inheritDoc}
558 +     * @since 1.8
559 +     */
560 +    @Override
561 +    public LongStream longs(long streamSize) {
562 +        return AbstractSpliteratorGenerator.longs(ThreadLocalRandomProxy.PROXY, streamSize);
563 +    }
564 +
565 +    /**
566 +     * {@inheritDoc}
567 +     * @implNote This method is implemented to be equivalent to
568 +     *           {@code longs(Long.MAX_VALUE)}.
569 +     * @since 1.8
570 +     */
571 +    @Override
572 +    public LongStream longs() {
573 +        return AbstractSpliteratorGenerator.longs(ThreadLocalRandomProxy.PROXY);
574 +    }
575 +
576 +    /**
577 +     * {@inheritDoc}
578 +     * @throws IllegalArgumentException {@inheritDoc}
579 +     * @since 1.8
580 +     */
581 +    @Override
582 +    public LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound) {
583 +        return AbstractSpliteratorGenerator.longs(ThreadLocalRandomProxy.PROXY, streamSize, randomNumberOrigin, randomNumberBound);
584 +    }
585 +
586 +    /**
587 +     * {@inheritDoc}
588 +     * @implNote This method is implemented to be equivalent to
589 +     *           {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
590 +     * @throws IllegalArgumentException {@inheritDoc}
591 +     * @since 1.8
592 +     */
593 +    @Override
594 +    public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
595 +        return AbstractSpliteratorGenerator.longs(ThreadLocalRandomProxy.PROXY, randomNumberOrigin, randomNumberBound);
596 +    }
597 +
598 +    /**
599 +     * {@inheritDoc}
600 +     * @throws IllegalArgumentException {@inheritDoc}
601 +     * @since 1.8
602 +     */
603 +    @Override
604 +    public DoubleStream doubles(long streamSize) {
605 +        return AbstractSpliteratorGenerator.doubles(ThreadLocalRandomProxy.PROXY, streamSize);
606 +    }
607 +
608 +    /**
609 +     * {@inheritDoc}
610 +     * @implNote This method is implemented to be equivalent to
611 +     *           {@code doubles(Long.MAX_VALUE)}.
612 +     * @since 1.8
613 +     */
614 +    @Override
615 +    public DoubleStream doubles() {
616 +        return AbstractSpliteratorGenerator.doubles(ThreadLocalRandomProxy.PROXY);
617 +    }
618 +
619 +    /**
620 +     * {@inheritDoc}
621 +     * @throws IllegalArgumentException {@inheritDoc}
622 +     * @since 1.8
623 +     */
624 +    @Override
625 +    public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
626 +        return AbstractSpliteratorGenerator.doubles(ThreadLocalRandomProxy.PROXY, streamSize, randomNumberOrigin, randomNumberBound);
627 +    }
628 +
629 +    /**
630 +     * {@inheritDoc}
631 +     * @implNote This method is implemented to be equivalent to
632 +     *           {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
633 +     * @throws IllegalArgumentException {@inheritDoc}
634 +     * @since 1.8
635 +     */
636 +    @Override
637 +    public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
638 +        return AbstractSpliteratorGenerator.doubles(ThreadLocalRandomProxy.PROXY, randomNumberOrigin, randomNumberBound);
639 +    }
640 +
641   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines