Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 7: ThreadLocalRandom generating the same random numbers

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?

like image 612
dogbane Avatar asked Aug 21 '11 16:08

dogbane


People also ask

Which is a limitation of the ThreadLocalRandom class?

int boundedRandomValue = ThreadLocalRandom. current(). nextInt(0, 100); Please note, 0 is the inclusive lower limit and 100 is the exclusive upper limit.

Is ThreadLocalRandom thread safe?

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.

Is Random thread safe in Java?

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.

What is ThreadLocalRandom in Java?

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.


3 Answers

Seems like there's an open bug regarding this issue. See here and here

like image 171
MByD Avatar answered Oct 17 '22 05:10

MByD


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

like image 45
ratchet freak Avatar answered Oct 17 '22 05:10

ratchet freak


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.

like image 1
Matt Avatar answered Oct 17 '22 06:10

Matt