Correct Usage of ThreadLocalRandom and the Predictable Random Number Pitfall in Java
The article explains why ThreadLocalRandom should not be stored in a static field, demonstrates how using ThreadLocalRandom.current().nextX(...) avoids predictable random numbers, compares behavior between JDK 11 and JDK 19, and provides the proper usage pattern with code examples.
In Java concurrency, it is recommended to use private static final ThreadLocal<T> for thread‑local variables and to wrap the set/get/remove operations in a utility class.
However, ThreadLocalRandom must not be stored in a static variable because doing so makes the generated random numbers predictable. The correct way to use it is:
ThreadLocalRandom.current().nextX(...)
The article shows an example where, under JDK 11, two threads produce identical random numbers. This occurs because the main thread calls ThreadLocalRandom.current() first, initializing the seed for the main thread, while the worker threads start with a seed value of zero. The seed is updated by adding a constant ( U.getLong(t, SEED) + GAMMA ), causing both threads to generate the same sequence.
Consequently, ThreadLocalRandom must be accessed via ThreadLocalRandom.current() in each thread to initialize its own seed.
In contrast, under JDK 19 the random numbers differ between threads because the algorithm incorporates the thread ID into the seed update, preventing the predictability observed in JDK 11.
In summary, the proper usage pattern is:
ThreadLocalRandom.current().nextX(...)
Following this approach ensures thread‑local random number generation remains unpredictable and safe across different JDK versions.
Cognitive Technology Team
Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.