CSR :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
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](https://openjdk.java.net/jeps/356). 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)
|