Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I prefer ThreadLocalRandom over ThreadLocal<Random>?

I'm looking to use (seeded) Random objects across multiple threads, and the javadocs pointed me to ThreadLocalRandom which looks great except I can't set the seed, so I can't ensure consistency among different threads or runs. Is there any practical reason to use ThreadLocalRandom or would it be acceptable to do something like the following:

// Pass returned ThreadLocal object to all threads which need it
public static ThreadLocal<Random> threadRandom(final long seed) {
    return new ThreadLocal<Random>(){
        @Override
        protected Random initialValue() {
            return new Random(seed);
        }
    };
}
like image 498
dimo414 Avatar asked Apr 02 '13 13:04

dimo414


People also ask

Why use ThreadLocalRandom?

Using ThreadLocalRandom in concurrent programs will typically encounter much less overhead and contention than using the global Random class. You can use ThreadLocalRandom when multiple tasks like a ForkJoinTask need random numbers in parallel in thread pools.

Is ThreadLocalRandom secure?

As described in its javadoc, ThreadLocalRandom is similar to Random (i.e. not secure) but with better performance in case of concurrent access. Instances of ThreadLocalRandom are not cryptographically secure. Consider instead using SecureRandom in security-sensitive applications.

Is Random nextInt thread safe?

random() guarantees it's safe for use by multiple threads. But the Random class does not.

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.


2 Answers

You can simply use Random, just make sure each Random object is only accessed within a single thread.

Random, being an ancient class like Vector, is unnecessarily heavily synchronized. They probably wanted to show off Java's threading support since it was a big deal at that time. Also Java was mostly intended to run on consumer PCs which mostly had a single processor so synchronization didn't impact scaling like it does today on multiprocessors.

Now an obvious answer is to provide a thread-unsafe version of Random, just like providing the thread-unsfae ArrayList as the alternative to Vector. That didn't happen, instead, we got ThreadLocalRandom. That is kind of odd, not sure what's the motivation behind that. In java8, ThreadLocalRandom is further optimized to operate directly on some int fields in the Thread object.

like image 90
ZhongYu Avatar answered Sep 20 '22 22:09

ZhongYu


The code for ThreadLocalRandom appears to be implemented as a ThreadLocal anyway (not exactly like you've put it, but probably close enough). I think what you have will work great.

like image 39
Rob I Avatar answered Sep 22 '22 22:09

Rob I