Master Java Random Generators: Math.random, Random, ThreadLocalRandom & SecureRandom

This article explains how Java's random number utilities—Math.random, java.util.Random, ThreadLocalRandom, and SecureRandom—work, covering their algorithms, thread‑safety, usage examples, code snippets, and when to prefer cryptographically secure generators for security‑critical applications.

Programmer DD
Programmer DD
Programmer DD
Master Java Random Generators: Math.random, Random, ThreadLocalRandom & SecureRandom

1. Math.random() static method

Math.random() returns a double between 0 (inclusive) and 1 (exclusive). Example usage:

for (int i = 0; i < 10; i++) {
    System.out.println(Math.random());
}

Result example:

0.3598613895606426 0.2666778145365811 0.25090731064243355 0.011064998061666276 0.600686228175639 0.9084006027629496 0.12700524654847833 0.6084605849069343 0.7290804782514261 0.9923831908303121

Implementation creates a single pseudorandom-number generator (java.util.Random) on first call and reuses it. The method is synchronized, making it thread‑safe.

Thread‑unsafe scenarios occur when separate generators are created with the same seed.

Thread 1 calls random() first, creates generator1 with current‑time seed.

Thread 2 calls random() first, creates generator2 with current‑time seed.

If both generators receive the same seed, they produce identical sequences.

Thread‑safe usage relies on the shared static generator.

2. java.util.Random utility class

Random uses a linear congruential generator (LCG) which is fast but predictable. It should not be used for security‑critical purposes; use SecureRandom instead.

Typical usage:

Random random = new Random();
for (int i = 0; i < 5; i++) {
    System.out.println(random.nextInt());
}

Result example:

-24520987 -96094681 -952622427 300260419 1489256498

Random is seeded with the current system time:

public Random() {
    this(seedUniquifier() ^ System.nanoTime());
}

Key methods include nextBoolean(), nextBytes(byte[]), nextDouble(), nextFloat(), nextGaussian(), nextInt(), nextInt(int), nextLong(), setSeed(long).

3. java.util.concurrent.ThreadLocalRandom

ThreadLocalRandom, introduced in JDK 7, extends java.util.Random but provides a separate generator per thread, reducing contention and improving performance.

Usage example:

public class JavaRandom {
    public static void main(String[] args) {
        new MyThread().start();
        new MyThread().start();
    }
}
class MyThread extends Thread {
    public void run() {
        for (int i = 0; i < 2; i++) {
            System.out.println(Thread.currentThread().getName() + ": " +
                ThreadLocalRandom.current().nextDouble());
        }
    }
}

Result example:

Thread-0: 0.13267085355389086 Thread-1: 0.1138484950410098 Thread-0: 0.17187774671469858 Thread-1: 0.9305225910262372

4. java.security.SecureRandom

SecureRandom is a cryptographically strong RNG. It gathers entropy from the operating system (e.g., mouse movements, keystrokes) and should be used for security‑sensitive applications.

Typical usage:

SecureRandom random1 = SecureRandom.getInstance("SHA1PRNG");
SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG");
for (int i = 0; i < 5; i++) {
    System.out.println(random1.nextInt() + " != " + random2.nextInt());
}

Result example:

704046703 != 2117229935 60819811 != 107252259 425075610 != -295395347 682299589 != -1637998900 -1147654329 != 1418666937

5. Random string generation

Apache Commons‑Lang provides RandomStringUtils for generating random strings. Maven dependency:

<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>

Example code:

public class RandomStringDemo {
    public static void main(String[] args) {
        String result = RandomStringUtils.random(64, false, true);
        System.out.println("random = " + result);
        result = RandomStringUtils.randomAlphabetic(64);
        System.out.println("random = " + result);
        result = RandomStringUtils.randomAscii(32);
        System.out.println("random = " + result);
        result = RandomStringUtils.random(32, 0, 20, true, true,
            "qw32rfHIJk9iQ8Ud7h0X".toCharArray());
        System.out.println("random = " + result);
    }
}

RandomStringUtils internally relies on java.util.Random.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavarandomThreadLocalRandomMath.randomRandom Number GenerationSecureRandom
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.