[cvs] / jsr166 / src / main / java / util / SplittableRandom.java Repository:
ViewVC logotype

Diff of /jsr166/src/main/java/util/SplittableRandom.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.17, Tue Aug 13 23:34:47 2013 UTC revision 1.18, Thu Aug 22 23:36:06 2013 UTC
# Line 25  Line 25 
25    
26  package java.util;  package java.util;
27    
28    import java.security.SecureRandom;
29  import java.net.InetAddress;  import java.net.InetAddress;
30  import java.util.concurrent.atomic.AtomicLong;  import java.util.concurrent.atomic.AtomicLong;
 import java.util.Spliterator;  
31  import java.util.function.IntConsumer;  import java.util.function.IntConsumer;
32  import java.util.function.LongConsumer;  import java.util.function.LongConsumer;
33  import java.util.function.DoubleConsumer;  import java.util.function.DoubleConsumer;
# Line 39  Line 39 
39  /**  /**
40   * A generator of uniform pseudorandom values applicable for use in   * A generator of uniform pseudorandom values applicable for use in
41   * (among other contexts) isolated parallel computations that may   * (among other contexts) isolated parallel computations that may
42   * generate subtasks. Class SplittableRandom supports methods for   * generate subtasks. Class {@code SplittableRandom} supports methods for
43   * producing pseudorandom numbers of type {@code int}, {@code long},   * producing pseudorandom numbers of type {@code int}, {@code long},
44   * and {@code double} with similar usages as for class   * and {@code double} with similar usages as for class
45   * {@link java.util.Random} but differs in the following ways:   * {@link java.util.Random} but differs in the following ways:
# Line 77  Line 77 
77   *   *
78   * </ul>   * </ul>
79   *   *
80     * <p>Instances of {@code SplittableRandom} are not cryptographically
81     * secure.  Consider instead using {@link java.security.SecureRandom}
82     * in security-sensitive applications. Additionally,
83     * default-constructed instances do not use a cryptographically random
84     * seed unless the {@linkplain System#getProperty system property}
85     * {@code java.util.secureRandomSeed} is set to {@code true}.
86    
87     *
88   * @author  Guy Steele   * @author  Guy Steele
89   * @author  Doug Lea   * @author  Doug Lea
90   * @since   1.8   * @since   1.8
# Line 138  Line 146 
146       * cases, this split must be performed in a thread-safe manner, so       * cases, this split must be performed in a thread-safe manner, so
147       * we use an AtomicLong to represent the seed rather than use an       * we use an AtomicLong to represent the seed rather than use an
148       * explicit SplittableRandom. To bootstrap the seeder, we start       * explicit SplittableRandom. To bootstrap the seeder, we start
149       * off using a seed based on current time and host. This serves as       * off using a seed based on current time and host unless the
150       * a slimmed-down (and insecure) variant of SecureRandom that also       * SecureRandomSeed property is set. This serves as a
151         * slimmed-down (and insecure) variant of SecureRandom that also
152       * avoids stalls that may occur when using /dev/random.       * avoids stalls that may occur when using /dev/random.
153       *       *
154       * It is a relatively simple matter to apply the basic design here       * It is a relatively simple matter to apply the basic design here
# Line 221  Line 230 
230      /**      /**
231       * The seed generator for default constructors.       * The seed generator for default constructors.
232       */       */
233      private static final AtomicLong seeder =      private static final AtomicLong seeder = new AtomicLong(initialSeed());
         new AtomicLong(mix64((((long)hashedHostAddress()) << 32) ^  
                              System.currentTimeMillis()) ^  
                        mix64(System.nanoTime()));  
234    
235      /**      private static long initialSeed() {
236       * Returns hash of local host IP address, if available; else 0.          try {  // ignore exceptions in accessing/parsing properties
237       */              String pp = System.getProperty
238      private static int hashedHostAddress() {                  ("java.util.secureRandomSeed");
239                if (pp != null && pp.equalsIgnoreCase("true")) {
240                    byte[] seedBytes = java.security.SecureRandom.getSeed(8);
241                    long s = (long)(seedBytes[0]) & 0xffL;
242                    for (int i = 1; i < 8; ++i)
243                        s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
244                    return s;
245                }
246            } catch (Exception ignore) {
247            }
248            int hh = 0; // hashed host address
249          try {          try {
250              return InetAddress.getLocalHost().hashCode();              hh = InetAddress.getLocalHost().hashCode();
251          } catch (Exception ex) {          } catch (Exception ignore) {
             return 0;  
252          }          }
253            return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^
254                    mix64(System.nanoTime()));
255      }      }
256    
257      // IllegalArgumentException messages      // IllegalArgumentException messages
# Line 406  Line 423 
423       * Returns a pseudorandom {@code int} value between zero (inclusive)       * Returns a pseudorandom {@code int} value between zero (inclusive)
424       * and the specified bound (exclusive).       * and the specified bound (exclusive).
425       *       *
426       * @param bound the bound on the random number to be returned.  Must be       * @param bound the upper bound (exclusive).  Must be positive.
      *        positive.  
427       * @return a pseudorandom {@code int} value between zero       * @return a pseudorandom {@code int} value between zero
428       *         (inclusive) and the bound (exclusive)       *         (inclusive) and the bound (exclusive)
429       * @throws IllegalArgumentException if {@code bound} is not positive       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 459  Line 475 
475       * Returns a pseudorandom {@code long} value between zero (inclusive)       * Returns a pseudorandom {@code long} value between zero (inclusive)
476       * and the specified bound (exclusive).       * and the specified bound (exclusive).
477       *       *
478       * @param bound the bound on the random number to be returned.  Must be       * @param bound the upper bound (exclusive).  Must be positive.
      *        positive.  
479       * @return a pseudorandom {@code long} value between zero       * @return a pseudorandom {@code long} value between zero
480       *         (inclusive) and the bound (exclusive)       *         (inclusive) and the bound (exclusive)
481       * @throws IllegalArgumentException if {@code bound} is not positive       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 514  Line 529 
529       * Returns a pseudorandom {@code double} value between 0.0       * Returns a pseudorandom {@code double} value between 0.0
530       * (inclusive) and the specified bound (exclusive).       * (inclusive) and the specified bound (exclusive).
531       *       *
532       * @param bound the bound on the random number to be returned.  Must be       * @param bound the upper bound (exclusive).  Must be positive.
      *        positive.  
533       * @return a pseudorandom {@code double} value between zero       * @return a pseudorandom {@code double} value between zero
534       *         (inclusive) and the bound (exclusive)       *         (inclusive) and the bound (exclusive)
535       * @throws IllegalArgumentException if {@code bound} is not positive       * @throws IllegalArgumentException if {@code bound} is not positive
# Line 533  Line 547 
547       * origin (inclusive) and bound (exclusive).       * origin (inclusive) and bound (exclusive).
548       *       *
549       * @param origin the least value returned       * @param origin the least value returned
550       * @param bound the upper bound       * @param bound the upper bound (exclusive)
551       * @return a pseudorandom {@code double} value between the origin       * @return a pseudorandom {@code double} value between the origin
552       *         (inclusive) and the bound (exclusive)       *         (inclusive) and the bound (exclusive)
553       * @throws IllegalArgumentException if {@code origin} is greater than       * @throws IllegalArgumentException if {@code origin} is greater than
# Line 594  Line 608 
608    
609      /**      /**
610       * Returns a stream producing the given {@code streamSize} number       * Returns a stream producing the given {@code streamSize} number
611       * of pseudorandom {@code int} values, each conforming to the       * of pseudorandom {@code int} values from this generator and/or one split
612       * given origin and bound.       * from it; each value conforms to the given origin (inclusive) and bound
613         * (exclusive).
614       *       *
615       * @param streamSize the number of values to generate       * @param streamSize the number of values to generate
616       * @param randomNumberOrigin the origin of each random value       * @param randomNumberOrigin the origin (inclusive) of each random value
617       * @param randomNumberBound the bound of each random value       * @param randomNumberBound the bound (exclusive) of each random value
618       * @return a stream of pseudorandom {@code int} values,       * @return a stream of pseudorandom {@code int} values,
619       *         each with the given origin and bound       *         each with the given origin (inclusive) and bound (exclusive)
620       * @throws IllegalArgumentException if {@code streamSize} is       * @throws IllegalArgumentException if {@code streamSize} is
621       *         less than zero, or {@code randomNumberOrigin}       *         less than zero, or {@code randomNumberOrigin}
622       *         is greater than or equal to {@code randomNumberBound}       *         is greater than or equal to {@code randomNumberBound}
# Line 620  Line 635 
635    
636      /**      /**
637       * Returns an effectively unlimited stream of pseudorandom {@code       * Returns an effectively unlimited stream of pseudorandom {@code
638       * int} values, each conforming to the given origin and bound.       * int} values from this generator and/or one split from it; each value
639         * conforms to the given origin (inclusive) and bound (exclusive).
640       *       *
641       * @implNote This method is implemented to be equivalent to {@code       * @implNote This method is implemented to be equivalent to {@code
642       * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.       * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
643       *       *
644       * @param randomNumberOrigin the origin of each random value       * @param randomNumberOrigin the origin (inclusive) of each random value
645       * @param randomNumberBound the bound of each random value       * @param randomNumberBound the bound (exclusive) of each random value
646       * @return a stream of pseudorandom {@code int} values,       * @return a stream of pseudorandom {@code int} values,
647       *         each with the given origin and bound       *         each with the given origin (inclusive) and bound (exclusive)
648       * @throws IllegalArgumentException if {@code randomNumberOrigin}       * @throws IllegalArgumentException if {@code randomNumberOrigin}
649       *         is greater than or equal to {@code randomNumberBound}       *         is greater than or equal to {@code randomNumberBound}
650       */       */
# Line 678  Line 694 
694    
695      /**      /**
696       * Returns a stream producing the given {@code streamSize} number of       * Returns a stream producing the given {@code streamSize} number of
697       * pseudorandom {@code long} values, each conforming to the       * pseudorandom {@code long} values from this generator and/or one split
698       * given origin and bound.       * from it; each value conforms to the given origin (inclusive) and bound
699         * (exclusive).
700       *       *
701       * @param streamSize the number of values to generate       * @param streamSize the number of values to generate
702       * @param randomNumberOrigin the origin of each random value       * @param randomNumberOrigin the origin (inclusive) of each random value
703       * @param randomNumberBound the bound of each random value       * @param randomNumberBound the bound (exclusive) of each random value
704       * @return a stream of pseudorandom {@code long} values,       * @return a stream of pseudorandom {@code long} values,
705       *         each with the given origin and bound       *         each with the given origin (inclusive) and bound (exclusive)
706       * @throws IllegalArgumentException if {@code streamSize} is       * @throws IllegalArgumentException if {@code streamSize} is
707       *         less than zero, or {@code randomNumberOrigin}       *         less than zero, or {@code randomNumberOrigin}
708       *         is greater than or equal to {@code randomNumberBound}       *         is greater than or equal to {@code randomNumberBound}
# Line 704  Line 721 
721    
722      /**      /**
723       * Returns an effectively unlimited stream of pseudorandom {@code       * Returns an effectively unlimited stream of pseudorandom {@code
724       * long} values, each conforming to the given origin and bound.       * long} values from this generator and/or one split from it; each value
725         * conforms to the given origin (inclusive) and bound (exclusive).
726       *       *
727       * @implNote This method is implemented to be equivalent to {@code       * @implNote This method is implemented to be equivalent to {@code
728       * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.       * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
729       *       *
730       * @param randomNumberOrigin the origin of each random value       * @param randomNumberOrigin the origin (inclusive) of each random value
731       * @param randomNumberBound the bound of each random value       * @param randomNumberBound the bound (exclusive) of each random value
732       * @return a stream of pseudorandom {@code long} values,       * @return a stream of pseudorandom {@code long} values,
733       *         each with the given origin and bound       *         each with the given origin (inclusive) and bound (exclusive)
734       * @throws IllegalArgumentException if {@code randomNumberOrigin}       * @throws IllegalArgumentException if {@code randomNumberOrigin}
735       *         is greater than or equal to {@code randomNumberBound}       *         is greater than or equal to {@code randomNumberBound}
736       */       */
# Line 727  Line 745 
745    
746      /**      /**
747       * Returns a stream producing the given {@code streamSize} number of       * Returns a stream producing the given {@code streamSize} number of
748       * pseudorandom {@code double} values, each between zero       * pseudorandom {@code double} values from this generator and/or one split
749       * (inclusive) and one (exclusive).       * from it; each value is between zero (inclusive) and one (exclusive).
750       *       *
751       * @param streamSize the number of values to generate       * @param streamSize the number of values to generate
752       * @return a stream of {@code double} values       * @return a stream of {@code double} values
# Line 746  Line 764 
764    
765      /**      /**
766       * Returns an effectively unlimited stream of pseudorandom {@code       * Returns an effectively unlimited stream of pseudorandom {@code
767       * double} values, each between zero (inclusive) and one       * double} values from this generator and/or one split from it; each value
768       * (exclusive).       * is between zero (inclusive) and one (exclusive).
769       *       *
770       * @implNote This method is implemented to be equivalent to {@code       * @implNote This method is implemented to be equivalent to {@code
771       * doubles(Long.MAX_VALUE)}.       * doubles(Long.MAX_VALUE)}.
# Line 763  Line 781 
781    
782      /**      /**
783       * Returns a stream producing the given {@code streamSize} number of       * Returns a stream producing the given {@code streamSize} number of
784       * pseudorandom {@code double} values, each conforming to the       * pseudorandom {@code double} values from this generator and/or one split
785       * given origin and bound.       * from it; each value conforms to the given origin (inclusive) and bound
786         * (exclusive).
787       *       *
788       * @param streamSize the number of values to generate       * @param streamSize the number of values to generate
789       * @param randomNumberOrigin the origin of each random value       * @param randomNumberOrigin the origin (inclusive) of each random value
790       * @param randomNumberBound the bound of each random value       * @param randomNumberBound the bound (exclusive) of each random value
791       * @return a stream of pseudorandom {@code double} values,       * @return a stream of pseudorandom {@code double} values,
792       * each with the given origin and bound       *         each with the given origin (inclusive) and bound (exclusive)
793       * @throws IllegalArgumentException if {@code streamSize} is       * @throws IllegalArgumentException if {@code streamSize} is
794       * less than zero       * less than zero
795       * @throws IllegalArgumentException if {@code randomNumberOrigin}       * @throws IllegalArgumentException if {@code randomNumberOrigin}
# Line 790  Line 809 
809    
810      /**      /**
811       * Returns an effectively unlimited stream of pseudorandom {@code       * Returns an effectively unlimited stream of pseudorandom {@code
812       * double} values, each conforming to the given origin and bound.       * double} values from this generator and/or one split from it; each value
813         * conforms to the given origin (inclusive) and bound (exclusive).
814       *       *
815       * @implNote This method is implemented to be equivalent to {@code       * @implNote This method is implemented to be equivalent to {@code
816       * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.       * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
817       *       *
818       * @param randomNumberOrigin the origin of each random value       * @param randomNumberOrigin the origin (inclusive) of each random value
819       * @param randomNumberBound the bound of each random value       * @param randomNumberBound the bound (exclusive) of each random value
820       * @return a stream of pseudorandom {@code double} values,       * @return a stream of pseudorandom {@code double} values,
821       * each with the given origin and bound       *         each with the given origin (inclusive) and bound (exclusive)
822       * @throws IllegalArgumentException if {@code randomNumberOrigin}       * @throws IllegalArgumentException if {@code randomNumberOrigin}
823       *         is greater than or equal to {@code randomNumberBound}       *         is greater than or equal to {@code randomNumberBound}
824       */       */

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.18

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8