Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8255395

Implement Enhanced Pseudo-Random Number Generators

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 17
    • core-libs
    • None
    • source
    • low
    • Developers may have subclassed and used names of new interface methods.
    • Java API
    • SE

      Summary

      This proposal introduces new common interface, RandomGenerator, that would allow consumers of random numbers to easily migrate between random number generation services or adapt to new random number generation algorithms as they are made available. This proposal also introduces a class, RandomGeneratorFactory, that can be used to locate and select random number generation algorithms as they become available. RandomGenerator and RandomGeneratorFactory are implementation outcomes from JEP 356 Enhanced Pseudo-Random Number Generators.

      Problem

      • Existing random number generators ( java.util.Random, java.security.SecureRandom, java.util.concurrent.ThreadLocalRandom, java.util.SplittableRandom ) require significant effort to adopt if the consumer wishes to change generators (algorithms).

      • The types of services supported by existing random number generators is inconsistent.

      • Adoption of new random number generation algorithms has a high order of complexity.

      Solution

      [Note: This proposal avoids the use of pseudo-random with the intent of future
      support for stochastic hardware based (noise) random number generation.]

      We propose the introduction of a common RandomGenerator interface to be implemented by all random generators used in Java. This common interface will allow easier transition between various implementations of a random number generator.

      RandomGenerator provides a comprehensive set of methods available from all random number generators; nextInt, nextLong, nextFloat, nextDouble, `nextBoolean and nextBytes. As well as bounded versions of the next methods, RandomGenerator provides methods for generating streams of ints, longs and doubles.

      To locate and construct application specific number generators, we propose to introduce the RandomGeneratorFactory<T> class. RandomGeneratorFactory<T> uses the ServiceLoader.Provider mechanism to locate all implementations of RandomGenerator.

      RandomGeneratorFactory<T> methods, such as all(), return java.util.stream.Stream of RandomGeneratorFactory to provide a query mechanism for locating relevant generators. For example, if the developer wants a sorted list of all available RandomGenerators then they can print such a list as follows;

      RandomGenerator.all()
                     .map(RandomGeneratorFactory::name)
                     .sorted()
                     .forEach(System.out::println);

      The RandomGeneratorFactory<T> class provides several query and predicate methods for filtering candidate RandomGenerators. For example, if the developer needs a generator closest to providing 128 state bits (assuming that a large number of state bits is more expensive) a query might look like;

      RandomGeneratorFactory<RandomGenerator> factory =
          RandomGenerator.all()
                         .filter(f -> 128 <= g.stateBits())
                         .sorted((f, g) -> Integer.compare(g.stateBits(), f.stateBits()))
                         .findFirst()
                         .orElseThrow();

      Once a RandomGeneratorFactory<T> is chosen, a RandomGenerator can then be instantiated and utilized;

      RandomGenerator rng = factory.create();
      System.out.println(rng.nextDouble());

      If the name of the RandomGenerator is known, then the RandomGenerator.factoryOf short-cut method can be used;

      RandomGeneratorFactory<RandomGenerator> factory = RandomGenerator.factoryOf("Random");
      RandomGenerator rng = factory.create();
      System.out.println(rng.nextDouble());

      As a further shortcut a new instance of RandomGenerator can be constructed directly using RandomGenerator.of;

      RandomGenerator rng = RandomGenerator.of("Random");
      System.out.println(rng.nextDouble());

      It is generally suggested that developers not use RandomGenerator.of by name due to future depreciation and the potential for better RandomGenerators. It is better to use selection queries.

      It is proposed that the four existing random number generators will be implementations of RandomGenerator; java.util.Random, java.security.SecureRandom, java.util.concurrent.ThreadLocalRandom and java.util.SplittableRandom.

      Note that java.util.concurrent.ThreadLocalRandom will not discoverable via RandomGeneratorFactory<T> due to its lack of a no-arg constructor ( ThreadLocalRandom.current() is used instead), but in all other respects java.util.concurrent.ThreadLocalRandom implements RandomGenerator.

      Finally, it is proposed that five specialized sub-interfaces of RandomGenerator be introduced; JumpableRandomGenerator, LeapableRandomGenerator, ArbitrariliyJumpableRandomGenerator, StreamableRandomGenerator and SplittableRandomGenerator. These sub-interfaces each provide a small set of specialized methods for handling specific needs. (see enclosed specdiff).

      Specification

      (see enclosed specdiff)

        1. overview-summary.html
          12 kB
          Joel Borggrén-Franck

            jlaskey Jim Laskey
            jlaskey Jim Laskey
            Roger Riggs
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: