I'm trying out Java 7's ThreadLocalRandom and see that it is generating exactly the same random numbers across multiple threads.
Here is my code, in which I create 5 threads and each thread prints out 5 random numbers:
//5 threads
for(int i = 0; i < 5 ; i++) {
final Thread thread = new Thread() {
@Override
public void run() {
System.out.print(Thread.currentThread().getName()+":");
//each thread prints 5 random numbers
for(int j = 0 ; j < 5; j++) {
final int random = ThreadLocalRandom.current().nextInt(1,100);
System.out.print(random + ",");
}
System.out.println();
}
};
thread.start();
thread.join();
}
Output:
Thread-0:1,93,45,75,29,
Thread-1:1,93,45,75,29,
Thread-2:1,93,45,75,29,
Thread-3:1,93,45,75,29,
Thread-4:1,93,45,75,29,
Why am I getting the same random numbers for each thread and for every execution of the program?
int boundedRandomValue = ThreadLocalRandom. current(). nextInt(0, 100); Please note, 0 is the inclusive lower limit and 100 is the exclusive upper limit.
Random is thread safe for use by multiple threads. But if multiple threads use the same instance of Random , the same seed is shared by multiple threads.
Instances of Random are thread–safe. Although, if the same instances are used across threads they may suffer from contention and result in poor performance. The Instances of Random are not cryptographically safe and therefore should not be used for security-sensitive applications.
public class ThreadLocalRandom extends Random. A random number generator isolated to the current thread. Like the global Random generator used by the Math class, a ThreadLocalRandom is initialized with an internally generated seed that may not otherwise be modified.
Seems like there's an open bug regarding this issue. See here and here
googling for the "ThreadLocalRandom source" gave me http://www.assembla.com/code/scala-eclipse-toolchain/git/nodes/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java
long/short of it: it uses a ThreadLocal<ThreadLocalRandom>
which calls the no-arg constructor for construction
that no-arg constructor is
/**
* Constructor called only by localRandom.initialValue.
* We rely on the fact that the superclass no-arg constructor
* invokes setSeed exactly once to initialize.
*/
ThreadLocalRandom() {
super();
}
the no-arg super in Random calls this(long) with a unique seed
HOWEVER that constructor does
public Random(long seed) {
this.seed = new AtomicLong(initialScramble(seed));
}
i.e. not the expected behavior from documentation
and ThreadLocalRandom doesn't/can't use the private seed
Isn't this because the threads are being created at roughly the same time and thus getting seeded the same value from the timer? I was under the impression that was how that worked, though I may be mistaken.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With