I have two options of code:
Option 1
int myFunc() {
return new Random().nextInt();
}
Or:
Option 2
Quick Code:
// For occasional tasks that just need an average quality random number
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.execute( () -> {
ThreadLocalRandom.current().nextInt(); // Fast and unique!
} );
// For SecureRandom, high quality random number
final Random r = new SecureRandom();
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.execute( () -> {
r.nextInt(); // sun.security.provider.NativePRNG uses singleton. Can't dodge contention.
} );
// Apache Common Math - Mersenne Twister - decent and non-singleton
int cpu = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool( cpu );
Map random = new WeakHashMap<>( cpu, 1.0f );
executor.execute( ()-> {
RandomGenerator r;
synchronized ( random ) { // Get or create generator.
r = random.get( Thread.currentThread() );
if ( r == null ) random.put( Thread.currentThread(), r = new MersenneTwister() );
}
r.nextInt( 1000 );
} );
Explanation:
Random
of same seed will yield same numbers.
In theory, new Random()
in each thread does not guarantee different seed.
In practice, new Random()
in each thread basically always get different seeds.
zapl suggested ThreadLocalRandom.current().nextInt()
. Great idea.
Random
, but it is also a linear congruential generator.SecureRandom
, which produce better quality random numbers."uniformally distributed" is just one small part of randomness tests.
Random
is somewhat uniform, and its result can be predicted given just two values.SecureRandom
in each thread.Note: Implementation details deduced from Java 8 source code. Future Java version may change; for example,
ThreadLocalRandom
is using sun.misc.Unsafe to store the seeds, which may be removed in Java 9 forcing ThreadLocalRandom to find a new way to work without contention.