Over a million developers have joined DZone.

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

Secure your Java app or API service quickly and easily with Okta's user authentication and authorization libraries. Developer accounts are free forever. Try Okta Instead.

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.


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:
    • 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


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.

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


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.


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

Secure your Java app or API service quickly and easily with Okta's user authentication and authorization libraries. Developer accounts are free forever. Try Okta Instead.

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 }}