Java
Random Numbers
Programming
Coding
Duplicate Content

Getting random numbers in Java

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Generating random numbers in Java is simple once you choose the right class for the job. The hard part is not syntax, but understanding the difference between ordinary pseudo-random values, thread-friendly generators, and cryptographically secure randomness.

Choose the Right Random API

Java gives you several ways to generate random values, and they are not interchangeable.

Use Random when you want a straightforward pseudo-random generator for simple programs, tests, or simulations. Use ThreadLocalRandom when many threads need random values without sharing a single generator. Use SecureRandom when the numbers protect passwords, tokens, session IDs, or anything security-sensitive.

That distinction matters because most “random” APIs in general-purpose programming are deterministic pseudo-random generators. They are excellent for games and sampling, but they are not safe for secrets.

Basic Random Numbers With Random

java.util.Random is the classic starting point. It can generate integers, booleans, doubles, and byte arrays.

java
1import java.util.Random;
2
3public class RandomDemo {
4    public static void main(String[] args) {
5        Random random = new Random();
6
7        int anyInt = random.nextInt();
8        int zeroToNine = random.nextInt(10);
9        double zeroToOne = random.nextDouble();
10
11        System.out.println("Any int: " + anyInt);
12        System.out.println("0..9: " + zeroToNine);
13        System.out.println("0.0..1.0: " + zeroToOne);
14    }
15}

A common beginner question is how to generate a value in a custom range. The key rule is that the upper bound is exclusive.

For an integer from min through max, inclusive:

java
1import java.util.Random;
2
3public class InclusiveRangeDemo {
4    public static void main(String[] args) {
5        int min = 5;
6        int max = 12;
7
8        Random random = new Random();
9        int value = random.nextInt(max - min + 1) + min;
10
11        System.out.println(value);
12    }
13}

If you forget that the upper bound is exclusive, your code will be off by one.

Better Concurrency With ThreadLocalRandom

In multi-threaded code, ThreadLocalRandom is usually a better default than sharing one Random instance. Each thread uses its own generator, which avoids unnecessary contention.

java
1import java.util.concurrent.ThreadLocalRandom;
2
3public class ThreadLocalRandomDemo {
4    public static void main(String[] args) {
5        int value = ThreadLocalRandom.current().nextInt(100, 201);
6        double score = ThreadLocalRandom.current().nextDouble(0.5, 1.0);
7
8        System.out.println("100..200: " + value);
9        System.out.println("0.5..1.0: " + score);
10    }
11}

This is especially useful in web servers, background workers, and parallel simulations where many requests may need random values at the same time.

Use SecureRandom for Security

If the random value protects something important, use SecureRandom. Session tokens, password reset links, invitation codes, and cryptographic keys should never come from Random.

java
1import java.security.SecureRandom;
2import java.util.HexFormat;
3
4public class SecureRandomDemo {
5    public static void main(String[] args) {
6        SecureRandom secureRandom = new SecureRandom();
7
8        byte[] tokenBytes = new byte[16];
9        secureRandom.nextBytes(tokenBytes);
10
11        String token = HexFormat.of().formatHex(tokenBytes);
12        System.out.println(token);
13    }
14}

SecureRandom may be a little slower, but that is the correct tradeoff when unpredictability matters.

Streams and Modern Style

Java also supports generating streams of random values, which is useful when you want many numbers and plan to process them functionally.

java
1import java.util.Random;
2
3public class StreamDemo {
4    public static void main(String[] args) {
5        Random random = new Random();
6
7        random.ints(5, 1, 7)
8              .forEach(System.out::println);
9    }
10}

This prints five integers from 1 through 6. Again, the upper bound is exclusive.

For data-heavy or simulation workloads, stream-based generation can make code cleaner and easier to combine with filtering, mapping, and aggregation.

Seeding and Reproducibility

Sometimes you do not want true unpredictability. In tests or simulations, repeatable output is often better because it makes failures reproducible.

java
1import java.util.Random;
2
3public class SeededDemo {
4    public static void main(String[] args) {
5        Random random = new Random(42L);
6
7        System.out.println(random.nextInt(100));
8        System.out.println(random.nextInt(100));
9        System.out.println(random.nextInt(100));
10    }
11}

Using the same seed produces the same sequence each time. That is useful for debugging randomized algorithms, but it is the opposite of what you want for security.

Common Pitfalls

The most common pitfall is using Random for security-sensitive tokens. That creates values that may be guessable enough to matter.

Another frequent issue is misunderstanding inclusive and exclusive bounds. nextInt(10) returns 0 through 9, not 1 through 10.

A third mistake is creating many new generators in a tight loop. Reusing the right generator is usually cleaner and more predictable.

Finally, some developers reach for Math.random() everywhere. It works for quick scripts, but it is less explicit than choosing Random, ThreadLocalRandom, or SecureRandom based on the real requirement.

Summary

  • Use Random for general pseudo-random values in ordinary application code.
  • Use ThreadLocalRandom when many threads need random values efficiently.
  • Use SecureRandom for tokens, secrets, and cryptographic use cases.
  • Remember that integer upper bounds are exclusive unless you adjust the formula.
  • Seeded generators are useful for reproducible tests, but not for secure randomness.

Course illustration
Course illustration

All Rights Reserved.