JDK-8255395 : Implement Enhanced Pseudo-Random Number Generators
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.util
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 17
  • Submitted: 2020-10-26
  • Updated: 2024-05-07
  • Resolved: 2021-04-02
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
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)

Comments
*hmmm* Moving back to Approved, but I don't see how the type of T can be used to inform the operation of the factory since the factory's only input is a string.
02-04-2021

Minor correction to return type. Spares the user a cast. Change included here, bug in specdiff preventing an update. @@ -342,16 +342,19 @@ public final class RandomGeneratorFactory<T extends RandomGenerator> { * * @param name Name of random number generator * <a href="package-summary.html#algorithms">algorithm</a> + * @param <T> Sub-interface of {@link RandomGenerator} to produce * * @return {@link RandomGeneratorFactory} of {@link RandomGenerator} * * @throws NullPointerException if name is null * @throws IllegalArgumentException if the named algorithm is not found */ - public static RandomGeneratorFactory<RandomGenerator> of(String name) { + public static <T extends RandomGenerator> RandomGeneratorFactory<T> of(String name) { Objects.requireNonNull(name); - - return factoryOf(name, RandomGenerator.class); + @SuppressWarnings("unchecked") + RandomGeneratorFactory<T> factory = + (RandomGeneratorFactory<T>)factoryOf(name, RandomGenerator.class); + return factory; }
01-04-2021

Moving to Approved.
26-03-2021

Should ThreadLocalRandom.doubles​(long streamSize, double randomNumberOrigin, double randomNumberBound) continue to state that IllegalArgumentException if "streamSize is less than zero," This condition has been removed. The filtering behavior of RandomGeneratorFactory.all with respect to deprecation should be specification text rather than a note.
26-03-2021

Fixed and fixed.
26-03-2021

Don't see the since in the current code. Updated the relevant RandomGeneratorFactory @implNote to @implSpec.
25-03-2021

These comments are for the https://bugs.openjdk.java.net/secure/attachment/93766/random-doc-diffs.zip version. The exiting no-arg ThreadLocalRandom.nextFloat() method has an unneeded @since tag. Likewise, the no-arg nextDouble doesn't need a since 7 tag. And the since tags for the other nextDouble method can be dropped too. Observation: the no-arg jump/leap method return void rather than the type of the generator being advanced through its state cycle. This does not support a fluent style of programming, which may not be useful for these objects. Several of the implNotes in RandomGeneratorFactory look to be normative specification statements so would be better as implSpec or regular text. In particular the notes in "of" and "all". Moving to Provisional.
25-03-2021

Fixed.
23-03-2021

ThreadLocalRandom.nextDouble(double ) and ThreadLocalRandom.nextDouble​(double origin, double bound) are existing methods in ThreadLocalRandom but have @since 17 tags: 556 /** 557 * {@inheritDoc} 558 * @throws IllegalArgumentException {@inheritDoc} 559 * @implNote {@inheritDoc} 560 * @since 17 561 */ 562 public double nextDouble(double bound) { 563 return super.nextDouble(bound); 564 } 565 566 /** 567 * {@inheritDoc} 568 * @throws IllegalArgumentException {@inheritDoc} 569 * @implNote {@inheritDoc} 570 * @since 17 571 */ 572 public double nextDouble(double origin, double bound) { 573 return super.nextDouble(origin, bound); 574 } Existing methods in JDK 16: https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/concurrent/ThreadLocalRandom.html#nextDouble(double) https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/concurrent/ThreadLocalRandom.html#nextDouble(double,double)
23-03-2021

[~kganapureddy] adding or removing elements from the table in the specification is a spec change. An implementation may choose to provide additional algorithms not listed in the table. The deprecated status of an algorithm is similar in spirit, but not necessarily exactly the same as deprecated a class. Meaning, the algorithm deprecation need not be implemented by deprecating an implementation-only class, although it may be. Note tat in contrast to earlier iterations of the proposal, it is an intentional change to *not* explicitly expose classes for all the supported algorithms.
23-03-2021

Added note about ThreadLocalRandom as a footnote to the table.
22-03-2021

**SplittableRandom.doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) Bad update to throws clause excluding streamSize constraints?** ** Bad @since tag update? ** Significantly cleaned up ints, longs doubles javadoc. Should be exactly as JDK 16 notes. **nextDouble​(double bound) and nextDouble() look to be existing methods so should not get explicit @since tags here.** Missing the context here. Does seem correct and don't see a @since. **RandomGenerator.JumpableGenerator.{rngs(), rngs​(long streamSize)} The @implSpec text seems inapplicable for these methods.** The default implementation is precisely as described? Not sure I understand your comment.
22-03-2021

***the table of algorithms intentionally does not mention the deprecation status of the algorithms and it is an intention design that the deprecation status of an algorithm can be updated without a spec change.*** I believe the reason behind this could be some of the listed algorithms has no direct public class ( exposed via docs like legacy algorithms) associated in Java SE. ***These algorithms [in the table below] must be found with the current version of Java SE. A particular JDK implementation may recognize additional algorithms; check the JDK's documentation for details. The set of algorithm required by Java SE may be updated by changes to the Java SE specification. Over time, new algorithms may be added and old algorithms may be removed.*** From the above excerpt I understand adding any new or removal of any of these mentioned algorithms is a spec change ?
22-03-2021

[~kganapureddy], the table of algorithms intentionally does *not* mention the deprecation status of the algorithms and it is an intention design that the deprecation status of an algorithm can be updated without a spec change.
20-03-2021

[~jlaskey] My observations from the latest spec diff. **Package-Info Section:** 1) In addition, as another life-cycle phase, an algorithm may be deprecated. A deprecated algorithm is not recommended for use. If a required algorithm is deprecated, it may be removed in a future release. Due to advances in random number generator algorithm development and analysis, an algorithm may be deprecated during the lifetime of a particular Java SE release. Changing the deprecation status of an algorithm is not a specification change. **The deprecation status change for the standard algorithms mentioned in table would be a specification change.** 2) As ThreadLocalRandom is mentioned as must supported algorithm, **If ThreadLocalRandom can not be created using RandomGenerator.of("ThreadLocalRandom"); it can be mentioned as a Note.** **RandomGeneratorFactory** public String name() Implementation Note: Availability is determined by RandomGeneratorFactory using the service provider API to locate implementations of the RandomGenerator interface. RandomGenerators that are marked as deprecated are not included in the result. **Is this misplaced? it is supposed to be at : public static <T extends RandomGenerator> Stream<RandomGeneratorFactory<T>> all​(Class<T> category)**
19-03-2021

Partial comments on latest revision from 2021-03-18: SplittableRandom.doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) Bad update to throws clause excluding streamSize constraints? Bad @since tag update? nextDouble​(double bound) and nextDouble() look to be existing methods so should not get explicit @since tags here. RandomGenerator.JumpableGenerator.{rngs(), rngs​(long streamSize)} The @implSpec text seems inapplicable for these methods. Left comments in the PR about more use of inheritDoc and Override in the nested subinterfaces in RandomGenerator.
18-03-2021

**Note that not all updates to package-info that are in the PR seem to be reflected in the specdiff.** package-info are handled poorly by specdiff. You need to discard old results before running (thought it would overwrite.) -=-=-=-=- **As cleanup item, possibly done after this work goes in, review java.util.Random and the rest of the random-related API for consistent use of "(pseudo)random" vs. "pseudorandom". I don't have a preference for which is used, but old text in java.util.Random using one and next text uses the other.** I was never comfortable with (pseudo)random. Visually qwerky. The choice of pseudo came into question when it was though that at some point stochastic rngs might come on line. I'll change all to pseudorandom. -=-=-=-=- **General recommend check: by convention, when default methods are added, they should include @implSpec tags to describe what they do.** -==-=-=-=- **Typo in Random.nextLong "RandomRandom"** Fixed. **SplittableRandom.nextBytes: do we need the implNote?** Fixed. **ThreadLocalRandom.nextDouble() & nextDouble​(double bound) Incorrect to have a local @since tags because these methods have been in place in JDK 7.** Fixed. **RandomGenerator.ArbitrarilyJumpableGenerator Leapable, etc.** **Code review comment: don't bury the lede in these subinterfaces. Suggest rewriting** **"This interface is designed to provide a common protocol for objects that generate sequences of pseudorandom numbers (or Boolean values) and furthermore can easily jump forward, by an arbitrary amount, to a distant point in the state cycle. "** **to something like pithier like** **"Protocol for objects that generate sequences of pseudorandom values and can easily jump forward, by an arbitrary amount, to a distant point in the state cycle."** Okay. **RandomGenerator.ArbitrarilyJumpableGenerator** **Why does this subinterface include its own definition of** **void jump​(double distance) void jump()** **both of which are also defined in RandomGenerator.JumpableGenerator? Analogous comment for** **void leap() and RandomGenerator.LeapableGenerator.** The return type is different. **RandomGenerator.nextBoolean** **Move text to @implSpec** Done as above. **RandomGeneratorFactory.all() -- screen out deprecated / change name.** Already does. Can discuss use of all vs algorithms. I think this is a pedantic change. **RandomGeneratorFactory.isDeprecated -- sensible?** Absolutely. You may equally use RandomGeneratorFactory.of and RandomGenerator.of. More likely the former if used in a production environment. **Package java.util.random** **Suggest changing** **"This package contains classes and interfaces that support a generic API for random number generation in the JDK."** **to** **"This package contains classes and interfaces that support a generic API for random number generation. "** Fixed. **In** **"There are also some more specialized interfaces that describe more specialized categories of random number generators RandomGenerator.SplittableGenerator, RandomGenerator.JumpableGenerator, RandomGenerator.LeapableGenerator, and RandomGenerator.ArbitrarilyJumpableGenerator..."** **Please use {@link} tags with abbreviated text, such as replacing** **{@link RandomGenerator.SplittableGenerator}** **with** **{@link RandomGenerator.SplittableGenerator SplittableGenerator}** Fixed. **In "Choosing a Random Number Generator Algorithm", recommend putting the algorithm names in code markup.** Fixed. **The set of algorithms in Java SE needs to be stated as normative rather than informative. Therefore, the implNote should be just be regular (normative) text.** Fixed.
18-03-2021

Note that not all updates to package-info that are in the PR seem to be reflected in the specdiff. -=-=-=-=- As cleanup item, possibly done after this work goes in, review java.util.Random and the rest of the random-related API for consistent use of "(pseudo)random" vs. "pseudorandom". I don't have a preference for which is used, but old text in java.util.Random using one and next text uses the other. -=-=-=-=- General recommend check: by convention, when default methods are added, they should include @implSpec tags to describe what they do. -==-=-=-=- Typo in Random.nextLong "RandomRandom" SplittableRandom.nextBytes: do we need the implNote? ThreadLocalRandom.nextDouble() & nextDouble​(double bound) Incorrect to have a local @since tags because these methods have been in place in JDK 7. RandomGenerator.ArbitrarilyJumpableGenerator Leapable, etc. Code review comment: don't bury the lede in these subinterfaces. Suggest rewriting "This interface is designed to provide a common protocol for objects that generate sequences of pseudorandom numbers (or Boolean values) and furthermore can easily jump forward, by an arbitrary amount, to a distant point in the state cycle. " to something like pithier like "Protocol for objects that generate sequences of pseudorandom values and can easily jump forward, by an arbitrary amount, to a distant point in the state cycle." RandomGenerator.ArbitrarilyJumpableGenerator Why does this subinterface include its own definition of void jump​(double distance) void jump() both of which are also defined in RandomGenerator.JumpableGenerator? Analogous comment for void leap() and RandomGenerator.LeapableGenerator. RandomGenerator.nextBoolean Move text to @implSpec RandomGeneratorFactory.all() -- screen out deprecated / change name. RandomGeneratorFactory.isDeprecated -- sensible? Package java.util.random Suggest changing "This package contains classes and interfaces that support a generic API for random number generation *in the JDK*." to "This package contains classes and interfaces that support a generic API for random number generation. " In "There are also some more specialized interfaces that describe more specialized categories of random number generators RandomGenerator.SplittableGenerator, RandomGenerator.JumpableGenerator, RandomGenerator.LeapableGenerator, and RandomGenerator.ArbitrarilyJumpableGenerator..." Please use {@link} tags with abbreviated text, such as replacing {@link RandomGenerator.SplittableGenerator} with {@link RandomGenerator.SplittableGenerator SplittableGenerator} In "Choosing a Random Number Generator Algorithm", recommend putting the algorithm names in code markup. The set of algorithms in Java SE needs to be stated as normative rather than informative. Therefore, the implNote should be just be regular (normative) text.
15-03-2021

**java.util.Random** **longs** **Put old implementation code into @implSpec** **doubles -- better as implSpec** The confusion here is because there should be consistency between ints, longs and double. The @implXXXX should be @implSpec since they are identical in substance even though historically they may have been marked @implNote. Will change all to @implSpec. **Any new-in-17 splits/split methods in SplittableRandom should have @since 17 tags.** Done. **SplittableRandom.nextBytes -- looks like missing "@" for an "implNote"** Done. **ThreadLocalRandom -- new methods nextFloat​(float bound) and nextFloat​(float origin, float bound) should have @since tags** Done. **RandomGenerator.ArbitrarilyJumpableGenerator RandomGenerator.JumpableGenerator RandomGenerator.LeapableGenerator RandomGenerator.SplittableGenerator RandomGenerator.StreamableGenerator RandomGenerator** **The methods that are included in the same initial release as the type don't need their own @since tags.** Done **Shouldn't isDeprecated be on RandomGenerator rather than RandomGeneratorFactory? Per previous comments, I recommedn RandomGeneratorFactory.all() (or whatever the method is renamed to) screen out deprecated algorithms.** We could add to RandomGenerator, but that would require an instance of the class to use. The predicate is more appropriate for the factory as a filter. I will add to RandomGenerator but it is then required in both. all() already filters isDeprecated. public static Stream<RandomGeneratorFactory<RandomGenerator>> all() { Map<String, Provider<? extends RandomGenerator>> fm = getFactoryMap(); return fm.values() .stream() .filter(p -> !p.type().isAnnotationPresent(Deprecated.class)) <<<< .map(RandomGeneratorFactory::new); }
14-03-2021

java.util.Random longs Put old implementation code into @implSpec doubles -- better as implSpec Any new-in-17 splits/split methods in SplittableRandom should have @since 17 tags. SplittableRandom.nextBytes -- looks like missing "@" for an "implNote" ThreadLocalRandom -- new methods nextFloat​(float bound) and nextFloat​(float origin, float bound) should have @since tags RandomGenerator.ArbitrarilyJumpableGenerator RandomGenerator.JumpableGenerator RandomGenerator.LeapableGenerator RandomGenerator.SplittableGenerator RandomGenerator.StreamableGenerator RandomGenerator The methods that are included in the same initial release as the type don't need their own @since tags. Shouldn't isDeprecated be on RandomGenerator rather than RandomGeneratorFactory? Per previous comments, I recommedn RandomGeneratorFactory.all() (or whatever the method is renamed to) screen out deprecated algorithms.
13-03-2021

**Minor comments:** **In Random, please restore the updated text around the citations of The Art of Computer Programming.** Restored. **If we want to require the particular implementation techniques in Random, the javadoc tags should be @implSpec's rather than @implNote's.** Got fuzzy because legacy @implNotes should follow this rule as well (into the refactored code). Changed. **For SplittableRandom, I suggest removing the new @implNote sections unless there is a compelling reason to keep them. (Since SplittableRandom is final, there are fewer issues around document the exact algorithms for subclasses, etc.)** Removed. **Same general comment for ThreadLocalRandom and its @implNotes.** Same. **public static Stream> all() Returns a non-empty stream of all available RandomGeneratorFactory(s).** Done.
12-03-2021

In RandomGeneratorFactory, I recommend public static Stream<RandomGeneratorFactory<RandomGenerator>> all() Returns a stream of all available RandomGeneratorFactory(s). be changed to public static Stream<RandomGeneratorFactory<RandomGenerator>> all() Returns a non-empty stream of all available RandomGeneratorFactory(s). In other words, the spec should guarantee the platform provides at least one RandomGeneratorFactory. Likewise for getDefault(), recommend explicitly stating it has a non-null result.
10-03-2021

Minor comments: In Random, please restore the updated text around the citations of The Art of Computer Programming. If we want to *require* the particular implementation techniques in Random, the javadoc tags should be @implSpec's rather than @implNote's. For SplittableRandom, I suggest removing the new @implNote sections unless there is a compelling reason to keep them. (Since SplittableRandom is final, there are fewer issues around document the exact algorithms for subclasses, etc.) Same general comment for ThreadLocalRandom and its @implNotes. From discussion outside of this CSR exchange, I'll send suggested wording for some edits to the package-level docs.
09-03-2021

**In SplittableRandom:** **- the nextBytes method should have a local definition to host the @since 10 information.** Modified. **- the makeFooSpliterator and new splits methods should have @since tags** Added @since 17 RandomGenerator methods so that all inherited cases reflect @since 17 unless overridden. **- what is the rationale for adding the pseudo-code for the existing ints, longs, and doubles methods? The class is final so letting subclasses get correct behavior in their overrides isn't a concern. If the pseudo-code is kept, I suggest putting it explicitly into an implNote block to make clear it is informative rather than normative.** The code for these methods were refactored to reuse (inherit) code directly from Random. The pseudo-code thus origins in Random javadoc has been there since 1.8 (also true of other inherited pseudo-code from 1.0). Will follow advisement from below. **In ThreadLocalRandom:** **- because the class itself is from 1.7, the methods from 1.7 do not need explicit @since tags. These tags should be removed.** Had thought they were needed to override from super class. Realize now that @since is excluded from @inheritDoc. **- The pseudo-code refer to "class Random" rather than "class ThreadLocalRandom". Perhaps the javadoc issue would be addressed if the implement details where place in @implSpec blocks in Random so they would not be included when ThreadLocalRandom inheritDoc's the comments from Random.** Will modify Random. **In the random package summary, in the "Choosing a Random Number Generator Algorithm" section, I suggest giving a one or two sentence summary of the recognized algorithm names. Something like: "The recognized names include names from several algorithm families. The family names have common portions with configuration parameters substituted in." In other words, given some indication in early occurrences of names like "L64X128MixRandom" that the structure that looks to be there, is in fact there.** There are three groups of random number generator algorithm provided in Java; Legacy group, LXM group and Xoroshiro/Xoshiro group. The legacy group includes random number generators that existed before JDK 17; Random, ThreadLocalRandom, SplittableRandom and SecureRandom. Random (LCG) is the weakest of available algorithms and it is recommended that users migrate to newer algorithms. If an application requires a random number generator algorithm that is cryptographically secure, then it should continue to use an instance of the class {@link java.security.SecureRandom}. The algorithms in the LXM group use a similar algorithm. The parameters of the algorithm can be found in algorithm name. The numbers indicate the number of bits in the lower and upper state bits respectively. Mix indicates the algorithm uses mix congruency. StarStar indicates use a double multiplier. The algorithms in the Xoroshiro/Xoshiro are more traditional algorithms where the number in the name indicates the period. **For RandomGenerator, I recommend including an isDeprcated method which defaults to return false. This is for better long-term management of the set of generators used by the platform. For example, if in the future of the lifetime of 17u one of the named supported algorithms is found to be deficient in some way, it can be marked as deprecated. Explicit requests for it could still be fulfilled, but deprecated algorithms could by RandomGeneratorFactory.all().** Mentioned earlier that this scheme will not likely be effective. Will discuss in e-mail.
01-03-2021

In SplittableRandom: * the nextBytes method should have a local definition to host the @since 10 information. * the makeFooSpliterator and new splits methods should have @since tags * what is the rationale for adding the pseudo-code for the existing ints, longs, and doubles methods? The class is final so letting subclasses get correct behavior in their overrides isn't a concern. If the pseudo-code is kept, I suggest putting it explicitly into an implNote block to make clear it is informative rather than normative. In ThreadLocalRandom: * because the class itself is from 1.7, the methods from 1.7 do *not* need explicit @since tags. These tags should be removed. * The pseudo-code refer to "class Random" rather than "class ThreadLocalRandom". Perhaps the javadoc issue would be addressed if the implement details where place in @implSpec blocks in Random so they would *not* be included when ThreadLocalRandom inheritDoc's the comments from Random. In the random package summary, in the "Choosing a Random Number Generator Algorithm" section, I suggest giving a one or two sentence summary of the recognized algorithm names. Something like: "The recognized names include names from several algorithm families. The family names have common portions with configuration parameters substituted in." In other words, given some indication in early occurrences of names like "L64X128MixRandom" that the structure that looks to be there, is in fact there. For RandomGenerator, I recommend including an isDeprcated method which defaults to return false. This is for better long-term management of the set of generators used by the platform. For example, if in the future of the lifetime of 17u one of the named supported algorithms is found to be deficient in some way, it can be marked as deprecated. Explicit requests for it could still be fulfilled, but deprecated algorithms could by RandomGeneratorFactory.all(). Moving to Provisional.
26-02-2021

Changed as requested.
22-02-2021

> **Missing inheritDoc of IllegalArgumentException in Random's IntStream > ints​(long streamSize) ?** > This appears to be a bug in javadoc @inheritDoc not copying the throws. Manual duplication of the throws in Random might lead to a > greater maintenance issue (bug gets fixed). These stream methods > themselves have been promoted to the general RandomGenerator > interface, as are the next methods. I.E., all RandomGenerators support > streams. These general changes to Random might demote the importance > of the @since. Should I remove the @inheritDoc, manually duplicate the > javadoc or move the @since 1.8 to RandomGenerator? The exception specification of a method is inheritDoc'ed separately from the main body of the method. The idiom is @throws FooException {@inheritDoc} Examples can be found in java.lang, java.util, and elsewhere. One rationale for a separate inheritDoc for exception is that subtypes can want to throw *fewer* exceptions than the supertype, a non-throwing close method for an AutoCloseable subtype being one common case. The correct skeletal javadoc for a method moved up the type hierarchy would be something like: /** * {@inheritDoc} * @param p1 {@inheritDoc} * @since OLD_RELEASE_AFTER_INITIAL_RELEASE * @throws FooException {@inheritDoc} */
22-02-2021

Last specdiff includes java.util.random package info
20-02-2021

**Missing inheritDoc of IllegalArgumentException in Random's IntStream ints​(long streamSize) ?** This appears to be a bug in javadoc @inheritDoc not copying the throws. Manual duplication of the throws in Random might lead to a greater maintenance issue (bug gets fixed). These stream methods themselves have been promoted to the general RandomGenerator interface, as are the next methods. I.E., all RandomGenerators support streams. These general changes to Random might demote the importance of the @since. Should I remove the @inheritDoc, manually duplicate the javadoc or move the @since 1.8 to RandomGenerator? **In SplittableRandom, is the period at least 2^64 as stated later in the class-level javadoc or exactly 2^64 as in the newly added text?** Will remove "at least". **Checking that the new implementation requirements listed for various SplittableRandom methods are intended.** Action item? **At least for the methods added to ThreadLocalRandom after its initial release, it would be better in inheritDoc the methods' spec and include a ThreadLocalRandom-specific @since tag.** This suffers the same issue as Random @inheritDoc. **Code review comments left concerning the specification of the table of algorithms; the package-info file doesn't seem to be included in the latest specdiff.** The table of algorithms is present, but have had difficulty getting specdiff to include the package-info. Will try alternate approaches.
20-02-2021

Missing inheritDoc of IllegalArgumentException in Random's IntStream ints​(long streamSize) ? In SplittableRandom, is the period *at least* 2^64 as stated later in the class-level javadoc or exactly 2^64 as in the newly added text? Checking that the new implementation requirements listed for various SplittableRandom methods are intended. At least for the methods added to ThreadLocalRandom after its initial release, it would be better in inheritDoc the methods' spec and include a ThreadLocalRandom-specific @since tag. Code review comments left concerning the specification of the table of algorithms; the package-info file doesn't seem to be included in the latest specdiff. Moving to Provisional.
20-02-2021

Changes made
11-02-2021

How about "finite jump distance greater than or equal to 0.0"? That rules out infinity and NaN and allows zeros, assuming zeros are sensible. A table in the package-level would suffice if there were links to in from the methods that would use the names and assuming the table comes with sufficient disclaimers, etc.
11-02-2021

I suppose I could make zero invalid as well, "positive non-zero" value would be a clean definition. How about if I add a table of the supplied JDK RandomGenerators in the package-info?
10-02-2021

Response to prior comments: > What happens with zero jumps? If a zero jump is acceptable, -0.0 > should arguably be okay. It is "NaN" rather than "Nan". > > Zero is a no op. If negative is the restriction why would -0.0 be > allowed? Fixed NaN. There is no numerical distance between -0.0 and + 0.0, which is why they compare as equal under ==. Generally if +0.0 is accepted as a valid input, -0.0 should be too. There are operations, like dividing by zero, that distinguish between the signed zeros, but they are a minority of operations. > > How to get lists of names of known algorithms? Are some algorithms > specified to be supported (for now)? > > RandomGenerator.all().map(RandomGeneratorFactory::name).sorted().forEach(System.out::println); > > Not sure it makes sense to list. Someone from another company might > come up with several more algorithms, or the security teams retools > SecureRandom to use the new API. I think the RandomGenerator API is > fluid by design. I'll restate this feedback: "It would be comforting to know *something* about the set of valid names for random algorithms in a release." For example charsets are also found by name-based lookup, but there are several distinguished charsets that are specified to be present.
09-02-2021

**Moving back to Provisional; next round of comments:** **java.util.Random -- javadoc bug displaying internal immediate superclass?** Used the AbstractStringBuilder defense, but modified javadoc to use @hidden to treat internal classes as undocumented. Many fixes to javadoc required. **public int nextInt​(int bound) -- javadoc fail -- loss of information.** Restored. **What about the 1.8 era additions?** Moved up into shared abstract classes. Will make sure no LOI in spec and @inheritDoc + @since added. **makeIntsSpliterator -- don't list as being copied from an internal class -- javadoc issue?** Fixed. **SplittableRandom -- loss of specific method info likely okay** Agree **What is the expected use of ThreadLocalRandom.proxy?** Dropped - residual notion. **Future interactions with Loom? -- ThreadLocalRandom, etc.** Will check with Ron and Alan. **API design question: for** **RandomGenerator of()** **was** **Optional of()** **considered instead?** Worth discussing. **RandomGenerator.getDefault[Factory]** **Suggestion: instead of** **"Since algorithms will improve over time, there is no guarantee that this method will return the same algorithm each time."** **"Since algorithms will improve over time, there is no guarantee that this method will return the same algorithm over time."** Changed. **It would be odd if calls to these methods in the same JVM sessions returned different algorithms, etc., but would not be odd if different JDK versions returned different algorithms.** **At least some of the implNotes in RandomGenerator would be better as implSpec's. The operational behavior of the implementation of the default method is generally better as an @implSpec.** Changed. **ArbitrarilyJumpableGenerator.jump(double) -- what about non-integral jump distances? Should they be illegal arguments too?** Would be reasonable to have non-integral jumps. Example, if the ranges of values produced are less than one. **What happens with zero jumps? If a zero jump is acceptable, -0.0 should arguably be okay. It is "NaN" rather than "Nan".** Zero is a no op. If negative is the restriction why would -0.0 be allowed? Fixed NaN. **How to get lists of names of known algorithms? Are some algorithms specified to be supported (for now)?** RandomGenerator.all().map(RandomGeneratorFactory::name).sorted().forEach(System.out::println); Not sure it makes sense to list. Someone from another company might come up with several more algorithms, or the security teams retools SecureRandom to use the new API. I think the RandomGenerator API is fluid by design. **RandomGeneratorFactory.period -- shouldn't special period values be documented?** Not really used - will remove. **More / better documention of predicates -- intended meaning of is hardware, etc.** Will do. **If isLeapable equivalent to instanceof RandomGenerator.LeapableGenerator?** Fixed. :-)
02-02-2021

Moving to Draft ahead of response to latest round of CSR feedback.
26-01-2021

Moving back to Provisional; next round of comments: java.util.Random -- javadoc bug displaying internal immediate superclass? public int nextInt​(int bound) -- javadoc fail -- loss of information. What about the 1.8 era additions? makeIntsSpliterator -- don't list as being copied from an internal class -- javadoc issue? SplittableRandom -- loss of specific method info likely okay What is the expected use of ThreadLocalRandom.proxy? Future interactions with Loom? -- ThreadLocalRandom, etc. API design question: for RandomGenerator of() was Optional<RandomGenerator> of() considered instead? RandomGenerator.getDefault[Factory] Suggestion: instead of "Since algorithms will improve over time, there is no guarantee that this method will return the same algorithm each time." "Since algorithms will improve over time, there is no guarantee that this method will return the same algorithm *over* time." It would be odd if calls to these methods in the same JVM sessions returned different algorithms, etc., but would not be odd if different JDK versions returned different algorithms. At least some of the implNotes in RandomGenerator would be better as implSpec's. The operational behavior of the implementation of the default method is generally better as an @implSpec. ArbitrarilyJumpableGenerator.jump(double) -- what about non-integral jump distances? Should they be illegal arguments too? What happens with zero jumps? If a zero jump is acceptable, -0.0 should arguably be okay. It is "NaN" rather than "Nan". How to get lists of names of known algorithms? Are some algorithms specified to be supported (for now)? RandomGeneratorFactory.period -- shouldn't special period values be documented? More / better documention of predicates -- intended meaning of is hardware, etc. If isLeapable equivalent to instanceof RandomGenerator.LeapableGenerator?
21-01-2021

Request for review https://mail.openjdk.java.net/pipermail/core-libs-dev/2020-November/070885.html
05-11-2020

New specdiff attached.
05-11-2020

**Is it intentional that the operation definition of Random.nextInt is removed?** No. That seems to be a bug in the SpecDiff report. `Random.nextInt()` and `Random.nextInt(bounds)` both appear in the changes, but `Random.nextInt()` does not show up in Methods Detail list. **Some javadoc fails in the fields defined in RandomGenerator.** Will make the changes. **How can the type variable in RandomGeneratorFactory be put to use?** 99% of the time the type var will be `RandomGenerator` as in `RandomGeneratorFactory<RandomGenerator>`. However, if you want to use specialized interface methods you would use the specialized interface. Example; RandomGeneratorFactory<LeapableGenerator> leapableFactory = LeapableGenerator.all().findFirst(); LeapableGenerator leapable = leapableFactory.create(); leapable.leap();
04-11-2020

Moving to Provisional; a few comments: Is it intentional that the operation definition of Random.nextInt is removed? Some javdoc fails in the fields defined in RandomGenerator. How can the type variable in RandomGeneratorFactory be put to use?
30-10-2020