Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention an
From ThreadLocalRandom API Document
A random number generator isolated to the current thread. Like the
* global {@link java.util.Random} generator used by the {@link
* java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
* with an internally generated seed that may not otherwise be
* modified. When applicable, use of {@code ThreadLocalRandom} rather
* than shared {@code Random} objects in concurrent programs will
* typically encounter much less overhead and contention. Use of
* {@code ThreadLocalRandom} is particularly appropriate when multiple
* tasks (for example, each a {@link ForkJoinTask}) use random numbers
* in parallel in thread pools.
Random can be created multiple times / same Random Object would shared across multiple threads ( due to the fact safe to use) . How ever creating multiple instance / same resource access by multiple thread would cause overhead.
Instead of Creating instance per Thread and maintain the resource in ThreadLocal would be more perfect. since the instance is not shared across multiple Threads. and there are no public constructor , your should use the factory method to get it.
I would say, it is just Factory of Random Objects which maintains /caches instance per thread.