Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Managing Randomness in Java

DZone's Guide to

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.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

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 java.util.Random class.

Random

An instance of this class is used to generate a stream of pseudorandom numbers.
Javadoc

This root class provides basic random-number-generation capabilities, nothing mind-blowing.

  • Generate a single random:
    • boolean
    • byte array
    • double
    • float, whether uniform or from a Gaussian distribution
    • long
    • or int (from 0 to 232 or a specific bound)
  • Generate a stream of random:
    • int
    • long
    • or double

For more specialized needs, there are two child classes, ThreadLocalRandom and SecureRandom.

Random class hierarchy

ThreadLocalRandom

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.

Use of ThreadLocalRandom is particularly appropriate when multiple tasks (for example, each a ForkJoinTask) use random numbers in parallel in thread pools.
JavaDoc

Usage is like:

ThreadLocalRandom.current().nextX(...) // (where X is Int, Long, etc.)


There are some interesting things about ThreadLocalRandom:

  • Compared to Random, it adds additional random-generating methods with bounds for types long and double
  • It doesn’t use the next(int bits) for the other random-generating methods, to avoid the AtomicLong contention

SecureRandom

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

On the other hand, SecureRandom offers true randomness:

This class provides a cryptographically strong random number generator (RNG).
Javadoc

This class depends on a Provider and algorithm.

Provider

A Provider provides some or all parts of the Java Security API. It has a name e.g.SunRsaSign, and a version.

Algorithm

Pretty self-explanatory, e.g.NativePRNG

To obtain an instance of the class, one can call either:

  1. One of the available constructors
  2. One of the getInstance() static method
  3. The getInstanceStrong() static method

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.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
java ,randomness ,threadlocalrandom ,securerandom ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}