Package java.util.random


packagejava.util.random
This package contains classes and interfaces that support a generic API for random number generation.

These classes and interfaces support the definition and use of "random generators", a term covering what have traditionally been called "random number generators" as well as generators of other sorts of randomly chosen values (eg. booleans). These classes and interfaces cover not only deterministic (pseudorandom) algorithms but also generators of values that use some "truly random" physical source (stochastic algorithms perhaps making use of thermal noise, for example, or quantum-mechanical effects).

The principal interface isRandomGenerator, which provides methods for requesting individual values of typeint,long,float,double, orboolean chosen pseudorandomly from a uniform distribution; methods for requesting values of typedouble chosen pseudorandomly from a normal distribution or from an exponential distribution; and methods for creating streams of values of typeint,long, ordouble chosen pseudorandomly from a uniform distribution (such streams are spliterator-based, allowing for parallel processing of their elements). There are also static factory methods for creating an instance of a specific random number generator algorithm given its name.

The principal supporting class isRandomGeneratorFactory. This can be used to generate multiple random number generators for a specific algorithm.RandomGeneratorFactory also provides methods for selecting random number generator algorithms.

An important subsidiary interface isRandomGenerator.StreamableGenerator, which provides methods for creating spliterator-based streams ofRandomGenerator objects, allowing for parallel processing of these objects using multiple threads. UnlikeRandom, most implementations ofRandomGenerator arenot thread-safe. The intent is that instances should not be shared among threads; rather, each thread should have its own random generator(s) to use. The various pseudorandom algorithms provided by this package are designed so that multiple instances will (with very high probability) behave as if statistically independent.

For many purposes, these are the only two interfaces that a consumer of pseudorandom values will need. There are also some more specialized interfaces that describe more specialized categories of random number generatorsSplittableGenerator,JumpableGenerator,LeapableGenerator, andArbitrarilyJumpableGenerator that have specific strategies for creating statistically independent instances.

Using the Random Number Generator Interfaces

To get started, an application should first create one instance of a generator class. Assume that the contents of the packagejava.util.random has been imported:
import java.util.random.*;
Then one can choose a specific implementation by giving the name of a generator algorithm to the static methodRandomGenerator.of(java.lang.String), in which case aRandomGenerator is constructed without any seed value:
RandomGenerator g = RandomGenerator.of("L64X128MixRandom");
For a single-threaded application, this is all that is needed. One can then invoke methods ofg such asnextLong(),nextInt(),nextFloat(),nextDouble() andnextBoolean() to generate individual randomly chosen values. One can also use the methodsints(),longs() anddoubles() to create streams of randomly chosen values. The methodsnextGaussian() andnextExponential() draw floating-point values from nonuniform distributions.

For a multi-threaded application, one can repeat the preceding steps to create additionalRandomGenerators, but often it is preferable to use methods of the one single initially created generator to create others like it. (One reason is that some generator algorithms, if asked to create a new set of generators all at once, can make a special effort to ensure that the new generators are statistically independent.) If the initial generator implements the interfaceRandomGenerator.StreamableGenerator, then the methodrngs() can be used to create a stream of generators. If this is a parallel stream, then it is easy to get parallel execution by using themap() method on the stream.

For a multi-threaded application that forks new threads dynamically, another approach is to use an initial generator that implements the interfaceRandomGenerator.SplittableGenerator, which is then considered to "belong" to the initial thread for its exclusive use; then whenever any thread needs to fork a new thread, it first uses thesplit() method of its own generator to create a new generator, which is then passed to the newly created thread for exclusive use by that new thread.

Choosing a Random Number Generator Algorithm

Random number generator algorithms are organized in groups, as describedbelow.

The legacy group includes random number generators that existed before JDK 17: Random, ThreadLocalRandom, SplittableRandom, and SecureRandom. Random (LCG) is the weakest of the 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 classSecureRandom.

The algorithms in the LXM group are similar to each other. The parameters of each algorithm can be found in the algorithm name. The number after "L" indicates the number of state bits for the LCG subgenerator, and the number after "X" indicates the number of state bits for the XBG subgenerator. "Mix" indicates that the algorithm uses an 8-operation bit-mixing function; "StarStar" indicates use of a 3-operation bit-scrambler.

The algorithms in the Xoroshiro/Xoshiro group are more traditional algorithms (see David Blackman and Sebastiano Vigna, "Scrambled Linear Pseudorandom Number Generators," ACM Transactions on Mathematical Software, 2021); the number in the name indicates the number of state bits.

For applications (such as physical simulation, machine learning, and games) that do not require a cryptographically secure algorithm, this package provides multiple implementations of interfaceRandomGenerator that provide trade-offs among speed, space, period, accidental correlation, and equidistribution properties.

For applications with no special requirements,L64X128MixRandom has a good balance among speed, space, and period, and is suitable for both single-threaded and multi-threaded applications when used properly (a separate instance for each thread).

If the application uses only a single thread, thenXoroshiro128PlusPlus is even smaller and faster, and certainly has a sufficiently long period.

For an application running in a 32-bit hardware environment and using only one thread or a small number of threads,L32X64MixRandom may be a good choice.

For an application that uses many threads that are allocated in one batch at the start of the computation, either a "jumpable" generator such asXoroshiro128PlusPlus orXoshiro256PlusPlus may be used, or a "splittable" generator such asL64X128MixRandom orL64X256MixRandom may be used.

For an application that creates many threads dynamically, perhaps through the use of spliterators, a "splittable" generator such asL64X128MixRandom orL64X256MixRandom is recommended. If the number of generators created dynamically may be very large (millions or more), then using generators such asL128X128MixRandom orL128X256MixRandom, which use a 128-bit parameter rather than a 64-bit parameter for their LCG subgenerator, will make it much less likely that two instances use the same state cycle.

For an application that uses tuples of consecutively generated values, it may be desirable to use a generator that isk-equidistributed such thatk is at least as large as the length of the tuples being generated. The generatorL64X256MixRandom is provably 4-equidistributed, andL64X1024MixRandom is provably 16-equidistributed.

For applications that generate large permutations, it may be best to use a generator whose period is much larger than the total number of possible permutations; otherwise it will be impossible to generate some of the intended permutations. For example, if the goal is to shuffle a deck of 52 cards, the number of possible permutations is 52! (52 factorial), which is larger than 2225 (but smaller than 2226), so it may be best to use a generator whose period at least 2256, such asL64X256MixRandom orL64X1024MixRandom orL128X256MixRandom orL128X1024MixRandom. (It is of course also necessary to provide sufficiently many seed bits when the generator is initialized, or else it will still be impossible to generate some of the intended permutations.)

Random Number Generator Algorithms Available

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 algorithms 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.

In addition, as another life-cycle phase, an algorithm may bedeprecated. 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 isnot a specification change.

Available Algorithms
AlgorithmGroupPeriodStateBitsEquidistribution
L128X1024MixRandomLXMBigInteger.ONE.shiftLeft(1024).subtract(BigInteger.ONE).shiftLeft(128)11521
L128X128MixRandomLXMBigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE).shiftLeft(128)2561
L128X256MixRandomLXMBigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE).shiftLeft(128)3841
L32X64MixRandomLXMBigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE).shiftLeft(32)961
L64X1024MixRandomLXMBigInteger.ONE.shiftLeft(1024).subtract(BigInteger.ONE).shiftLeft(64)108816
L64X128MixRandomLXMBigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE).shiftLeft(64)1922
L64X128StarStarRandomLXMBigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE).shiftLeft(64)1922
L64X256MixRandomLXMBigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE).shiftLeft(64)3204
RandomLegacyBigInteger.ONE.shiftLeft(48)480
SplittableRandomLegacyBigInteger.ONE.shiftLeft(64)641
SecureRandomLegacyBigInteger.ZEROInteger.MAX_VALUEInteger.MAX_VALUE
ThreadLocalRandom*LegacyBigInteger.ONE.shiftLeft(64)641
Xoroshiro128PlusPlusXoroshiroBigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE)1281
Xoshiro256PlusPlusXoshiroBigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE)2563

* ThreadLocalRandom can only be accessed viaThreadLocalRandom.current().

Categories of Random Number Generator Algorithms

Historically, most pseudorandom generator algorithms have been based on some sort of finite-state machine with a single, large cycle of states; when it is necessary to have multiple threads use the same algorithm simultaneously, the usual technique is to arrange for each thread to traverse a different region of the state cycle. These regions may be doled out to threads by starting with a single initial state and then using a "jump function" that travels a long distance around the cycle (perhaps 264 steps or more); the jump function is applied repeatedly and sequentially, to identify widely spaced states that are then doled out, one to each thread, to serve as the initial state for the generator to be used by that thread. This strategy is supported by the interfaceRandomGenerator.JumpableGenerator. Sometimes it is desirable to support two levels of jumping (by long distances and byreally long distances); this strategy is supported by the interfaceRandomGenerator.LeapableGenerator. In this package, implementations of this interface include "Xoroshiro128PlusPlus" and "Xoshiro256PlusPlus". There is also an interfaceRandomGenerator.ArbitrarilyJumpableGenerator for algorithms that allow jumping along the state cycle by any user-specified distance; there are currently no implementations of this interface in this package.

A more recent category of "splittable" pseudorandom generator algorithms uses a large family of state cycles and makes some attempt to ensure that distinct instances use different state cycles; but even if two instances "accidentally" use the same state cycle, they are highly likely to traverse different regions of that shared state cycle. This strategy is supported by the interfaceRandomGenerator.SplittableGenerator. In this package, implementations of this interface include "L32X64MixRandom", "L64X128StarStarRandom", "L64X128MixRandom", "L64X256MixRandom", "L64X1024MixRandom", "L128X128MixRandom", "L128X256MixRandom", and "L128X1024MixRandom"; note that the classSplittableRandom also implements this interface.

The LXM Family of Random Number Generator Algorithms

The structure of the central nextLong (or nextInt) method of an LXM algorithm follows a suggestion in December 2017 by Sebastiano Vigna that using one Linear Congruential Generator (LCG) as a first subgenerator and one Xor-Based Generator (XBG) as a second subgenerator (rather than using two LCG subgenerators) would provide a longer period, superior equidistribution, scalability, and better quality. Each of the specific implementations here combines one of the best currently known XBG algorithms (xoroshiro128 or xoshiro256, described by Blackman and Vigna in "Scrambled Linear Pseudorandom Number Generators",ACM Transactions on Mathematical Software, 2021) with an LCG that uses one of the best currently known multipliers (found by a search for better multipliers in 2019 by Steele and Vigna, described in "Computationally Easy, Spectrally Good Multipliers for Congruential Pseudorandom Number Generators",Software: Practice and Experience (2021), doi:10.1002/spe.3030), and then applies either a mixing function identified by Doug Lea or or a simple scrambler proposed by Blackman and Vigna. Testing has confirmed that the LXM algorithm is far superior in quality to the SplitMix algorithm (2014) used bySplittableRandom (see Steele and Vigna, "LXM: Better Splittable Pseudorandom Number Generators (and Almost as Fast)",Proc. 2021 ACM OOPSLA Conference). Each class with a name of the formLpXqSomethingRandom uses some specific member of the LXM family of random number algorithms; "LXM" is short for "LCG, XBG, Mixer". Every LXM generator has two subgenerators; one is an LCG (Linear Congruential Generator) and the other is an XBG (Xor-Based Generator). Each output of an LXM generator is the result of combining state from the LCG with state from the XBG using a Mixing function (and then the state of the LCG and the state of the XBG are advanced).

The LCG subgenerator has an update step of the forms = m*s + a, wheres,m, anda are all binary integers of the same size, each havingp bits;s is the mutable state, the multiplierm is fixed (the same for all instances of a class) and the addenda is a parameter (a final field of the instance). The parametera is required to be odd (this allows the LCG to have the maximal period, namely 2p); therefore there are 2p−1 distinct choices of parameter. (When the size ofs is 128 bits, then we use the name "sh" below to refer to the high half ofs, that is, the high-order 64 bits ofs.)

The XBG subgenerator can in principle be any one of a wide variety of XBG algorithms; in this package it is always eitherxoroshiro128,xoshiro256, orxoroshiro1024, in each case without any final scrambler (such as "+" or "**") because LXM uses a separate Mixer later in the process. The XBG state consists of some fixed number ofint orlong fields, generally namedx0,x1, and so on, which can take on any values provided that they are not all zero. The collective total size of these fields isq bits; therefore the period of this subgenerator is 2q−1.

Because the periods 2p and 2q−1 of the two subgenerators are relatively prime, theperiod of any single instance of an LXM algorithm (the length of the series of generated values before it repeats) is the product of the periods of the subgenerators, that is, 2p(2q−1), which is just slightly smaller than 2(p+q). Moreover, if two distinct instances of the same LXM algorithm have differenta parameters, then their cycles of produced values will be different.

Generally speaking, among the "LpXq" generators, the memory required for an instance is 2p+q bits. (Ifq is 1024 or larger, the XBG state is represented as an array, so additional bits are needed for the array object header, and another 32 bits are used for an array index.)

Larger values ofp imply a lower probability that two distinct instances will traverse the same state cycle, and larger values ofq imply that the generator is equidistributed in a larger number of dimensions (this is provably true whenp is 64, and conjectured to be approximately true whenp is 128). A class with "Mix" in its name uses a fairly strong mixing function with excellent avalanche characteristics; a class with "StarStar" in its name uses a weaker but faster mixing function.

The specific LXM algorithms used in this package are all chosen so that the 64-bit values produced by thenextLong() method are exactly equidistributed (for example, for any specific instance of "L64X128MixRandom", over the course of its cycle each of the 264 possiblelong values will be produced 2128−1 times). The values produced by thenextInt(),nextFloat(), andnextDouble() methods are likewise exactly equidistributed. Some algorithms provide a further guarantee ofk-equidistribution for somek greater than 1, meaning that successive non-overlappingk-tuples of 64-bit values produced by thenextLong() method are exactly equidistributed (equally likely to occur).

The following table gives the period, state size (in bits), parameter size (in bits, including the low-order bit that is required always to be a 1-bit), and equidistribution property for each of the specific LXM algorithms used in this package.

Algorithm Properties
ImplementationPeriodState sizeParameter sizenextLong() values are
"L32X64MixRandom"232(264−1)96 bits32 bits
"L64X128StarStarRandom"264(2128−1)192 bits64 bits2-equidistributed and exactly equidistributed
"L64X128MixRandom"264(2128−1)192 bits64 bits2-equidistributed and exactly equidistributed
"L64X256MixRandom"264(2256−1)320 bits64 bits4-equidistributed and exactly equidistributed
"L64X1024MixRandom"264(21024−1)1088 bits64 bits16-equidistributed and exactly equidistributed
"L128X128MixRandom"2128(2128−1)256 bits128 bitsexactly equidistributed
"L128X256MixRandom"2128(2256−1)384 bits128 bitsexactly equidistributed
"L128X1024MixRandom"2128(21024−1)1152 bits128 bitsexactly equidistributed
For the algorithms listed above whose names begin withL32, the 32-bit values produced by thenextInt() method are exactly equidistributed, but the 64-bit values produced by thenextLong() method are not exactly equidistributed.

For the algorithms listed above whose names begin withL64 orL128, the 64-bit values produced by thenextLong() method areexactly equidistributed: every instance, over the course of its cycle, will produce each of the 264 possiblelong values exactly the same number of times. For example, any specific instance of "L64X256MixRandom", over the course of its cycle each of the 264 possiblelong values will be produced 2256−1 times. The values produced by thenextInt(),nextFloat(), andnextDouble() methods are likewise exactly equidistributed.

In addition, for the algorithms listed above whose names begin withL64, the 64-bit values produced by thenextLong() method arek-equidistributed (but not exactlyk-equidistributed). To be precise, and taking "L64X256MixRandom" as an example: for any specific instance of "L64X256MixRandom", consider the (overlapping) length-4 subsequences of the cycle of 64-bit values produced bynextLong() (assuming no other methods are called that would affect the state). There are 264(2256−1) such subsequences, and each subsequence, which consists of 4 64-bit values, can have one of 2256 values. Of those 2256 subsequence values, nearly all of them (2256−264) occur 264 times over the course of the entire cycle, and the other 264 subsequence values occur only 264−1 times. So the ratio of the probability of getting any specific one of the less common subsequence values and the probability of getting any specific one of the more common subsequence values is 1−2-64. (Note that the set of 264 less-common subsequence values will differ from one instance of "L64X256MixRandom" to another, as a function of the additive parameter of the LCG.) The values produced by thenextInt(),nextFloat(), andnextDouble() methods are likewise 4-equidistributed (but not exactly 4-equidistributed).

The next table gives the LCG multiplier value, the name of the specific XBG algorithm used, the specific numeric parameters for that XBG algorithm, and the mixing function for each of the specific LXM algorithms used in this package. (Note that the multiplier used for the 128-bit LCG cases is 65 bits wide, so the constant0x1d605bbb58c8abbfdL shown in the table cannot actually be used in code; instead, only the 64 low-order bits0xd605bbb58c8abbfdL are represented in the source code, and the missing 1-bit is handled through special coding of the multiply-add algorithm used in the LCG.)

LXM Multipliers
ImplementationLCG multipliermXBG algorithmXBG parametersMixing function
"L32X64MixRandom"0xadb4a92dxoroshiro64, version 1.0(26, 9, 13)mixLea32(s+x0)
"L64X128StarStarRandom"0xd1342543de82ef95Lxoroshiro128, version 1.0(24, 16, 37)Long.rotateLeft((s+x0)* 5, 7) * 9
"L64X128MixRandom"0xd1342543de82ef95Lxoroshiro128, version 1.0(24, 16, 37)mixLea64(s+x0)
"L64X256MixRandom"0xd1342543de82ef95Lxoshiro256, version 1.0(17, 45)mixLea64(s+x0)
"L64X1024MixRandom"0xd1342543de82ef95Lxoroshiro1024, version 1.0(25, 27, 36)mixLea64(s+x0)
"L128X128MixRandom"0x1d605bbb58c8abbfdLxoroshiro128, version 1.0(24, 16, 37)mixLea64(sh+x0)
"L128X256MixRandom"0x1d605bbb58c8abbfdLxoshiro256, version 1.0(17, 45)mixLea64(sh+x0)
"L128X1024MixRandom"0x1d605bbb58c8abbfdLxoroshiro1024, version 1.0(25, 27, 36)mixLea64(sh+x0)

Since:
17
  • Related Packages
    Package
    Description
    Contains the collections framework, some internationalization support classes, a service loader, properties, random number generation, string parsing and scanning classes, base64 encoding and decoding, a bit array, and several miscellaneous utility classes.
  • Class
    Description
    TheRandomGenerator interface is designed to provide a common protocol for objects that generate random or (more typically) pseudorandom sequences of numbers (or Boolean values).
    This interface is designed to provide a common protocol for objects that generate sequences of pseudorandom values and can easilyjump forward, by an arbitrary amount, to a distant point in the state cycle.
    This interface is designed to provide a common protocol for objects that generate pseudorandom values and can easilyjump forward, by a moderate amount (ex. 264) to a distant point in the state cycle.
    This interface is designed to provide a common protocol for objects that generate sequences of pseudorandom values and can easily not only jump but alsoleap forward, by a large amount (ex. 2128), to a very distant point in the state cycle.
    This interface is designed to provide a common protocol for objects that generate sequences of pseudorandom values and can besplit into two objects (the original one and a new one) each of which obey that same protocol (and therefore can be recursively split indefinitely).
    TheRandomGenerator.StreamableGenerator interface augments theRandomGenerator interface to provide methods that return streams ofRandomGenerator objects.
    This is a factory class for generating multiple random number generators of a specificalgorithm.