Managing Randomness in Java
Managing Randomness in Java
Let's go over some of your options for playing with random numbers in Java, including overviews of the Random class, ThreadLocalRandom, and SecureRandom.
Join the DZone community and get the full member experience.Join For Free
If you already had to manage some degree of randomness on Java, chances are that you've become acquainted with the
Math.random() methods. However, the previous method returns a double. Beyond very basic use-cases, another option has to be considered in the form of the
An instance of this class is used to generate a stream of pseudorandom numbers.
This root class provides basic random-number-generation capabilities, nothing mind-blowing.
- Generate a single random:
float, whether uniform or from a Gaussian distribution
int(from 0 to 232 or a specific bound)
- Generate a stream of random:
For more specialized needs, there are two child classes,
One problem about the
Random class is that it’s based on an
AtomicLong for number generation. It’s thread-safe by definition, but it may cause performance issues if used by too many threads at once.
ThreadLocalRandomis particularly appropriate when multiple tasks (for example, each a
ForkJoinTask) use random numbers in parallel in thread pools.
Usage is like:
ThreadLocalRandom.current().nextX(...) // (where X is Int, Long, etc.)
There are some interesting things about
- Compared to
Random, it adds additional random-generating methods with bounds for types
- It doesn’t use the
next(int bits)for the other random-generating methods, to avoid the
The important bit about
Random is that it doesn't provide true randomness, but only pseudo-randomness. From the Javadoc of the
next(int bits)(upon which all other random generator methods depend):
This is a linear congruential pseudorandom number generator, as defined by D. H. Lehmer and described by Donald E. Knuth in The Art of Computer Programming, Volume 3: Seminumerical Algorithms, section 3.2.1.
On the other hand,
SecureRandom offers true randomness:
This class provides a cryptographically strong random number generator (RNG).
This class depends on a Provider and algorithm.
Provider provides some or all parts of the Java Security API. It has a name e.g.
SunRsaSign, and a version.
Pretty self-explanatory, e.g.
To obtain an instance of the class, one can call either:
- One of the available constructors
- One of the
I'd suggest using the last option, as it will throw an exception if no "strong" random algorithm is available.
A "strong" algorithm is defined by the
securerandom.strongAlgorithms security property. Running
Security.getProperty("securerandom.strongAlgorithms") on my local dev environment yields
NativePRNGBlocking:SUN. I'll let everyone decide whether an algorithm prefixed with PNRG (Pseudo-Random Number Generator...) is good enough.
Remember to check
$JAVA_HOME/lib/security/java.security to manage the security configuration of your JVM.
Published at DZone with permission of Nicolas Frankel , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.