Pseudorandom number generators produce sequences that appear random but are generated deterministically using mathematical formulas. Java's Random class implements a linear congruential generator (LCG) based on a 48-bit seed value.
Core Algorithm Implementation
The LCG algorithm follows the recurrence relation:
Xn+1 = (a * Xn + c) mod m
In Java's implementation:
private static final long coefficient = 0x5DEECE66DL;
private static final long increment = 0xBL;
private static final long modulus = (1L << 48) - 1;
protected int generateBits(int bitCount) {
long currentSeed, nextSeed;
AtomicLong seedRef = this.seed;
do {
currentSeed = seedRef.get();
nextSeed = (currentSeed * coefficient + increment) & modulus;
} while (!seedRef.compareAndSet(currentSeed, nextSeed));
return (int)(nextSeed >>> (48 - bitCount));
}
The bitwise AND operation with modulus is equivalent to modulo 2^48, as modulus = 2^48 - 1 creates a bitmask that preserves the lower 48 bits.
Seed Initialization
Java employs sophisticated seed generation combining system time and multiplicative scrambling:
private static long generateUniqueSeed() {
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
public Random() {
this(generateUniqueSeed() ^ System.nanoTime());
}
This approach combines:
- A base seed value (8682522807148012L)
- Multiplicative scrambling with a large prime constant
- XOR with high-resolusion system time
Bounded Random Number Generation
For generating integers within a specific range [0, n):
public int nextBoundedInt(int upperBound) {
if (upperBound <= 0)
throw new IllegalArgumentException("Upper bound must be positive");
if ((upperBound & -upperBound) == upperBound)
return (int)((upperBound * (long)generateBits(31)) >> 31);
int randomBits, result;
do {
randomBits = generateBits(31);
result = randomBits % upperBound;
} while (randomBits - result + (upperBound - 1) < 0);
return result;
}
The condition (upperBound & -upperBound) == upperBound efficiently checks if the upper bound is a power of two using two's complement properties.
Algorithm Characteristics
- Period: The generator has a maximum period of 2^48
- Thread Safety: Implemented using atomic operations on the seed
- Limitations: Sequential correlation between generated values
- Cryptographic Security: Not suitable for security-sensitive applications
For cryptographic purposes, use java.security.SecureRandom which provides cryptographically strong random numbers.