Is Random class thread safe?

2019-01-22 04:46发布

Is it valid to share one instance of the Random class between multiple threads? And to call nextInt(int) from multiple threads in particular?

8条回答
别忘想泡老子
2楼-- · 2019-01-22 05:32

As said, it is thread save, but it may be wise to use java.util.concurrent.ThreadLocalRandom according to this article (link dead). ThreadLocalRandom is also a subclass of Random, so it is backwards compatible.

The article linked compared profiling results of the different Random classes: java.util.Random, java.util.concurrent.ThreadLocalRandom and java.lang.ThreadLocal<java.util.Random>. The results showed, that the usage of ThreadLocalRandom is most performant, followed by ThreadLocal and worst performing Random itself.

查看更多
我想做一个坏孩纸
3楼-- · 2019-01-22 05:33

Here's how I dealt with the problem without assuming that Random uses atomic variables. It can still randomly collide if currentTime * thread id is equal some time in the future, but that's rare enough for my needs. To truly avoid the possibility of collisions, you could have each request wait for a unique clock timestamp.

/**
 * Thread-specific random number generators. Each is seeded with the thread
 * ID, so the sequence of pseudo-random numbers are unique between threads.
 */
private static ThreadLocal<Random> random = new ThreadLocal<Random>() {
    @Override
    protected Random initialValue() {
        return new Random(
            System.currentTimeMillis() *
            Thread.currentThread().getId());
    }
};
查看更多
Ridiculous、
4楼-- · 2019-01-22 05:35

There's no reason multiple threads can't all use the same Random. However, since the class is not explicitly thread-safe and maintains a sequence of pseudo-random numbers via the seed. Multiple threads may end up with the same random number. It would be better to create multiple Randoms for each thread and seed them differently.

EDIT: I've just noticed that the Sun implementation uses AtomicLong so i guess that is Thread-safe (as also noted by Peter Lawrey (+1)).

EDIT2: OpenJDK also uses AtomicLong for the seed. As others have said though it's still not good to rely on this.

查看更多
forever°为你锁心
5楼-- · 2019-01-22 05:39

Acording to the documentation, Math.random() guarantees it's safe for use by multiple threads. But the Random class does not. I would assume then you'll have to synchronize that yourself.

查看更多
戒情不戒烟
6楼-- · 2019-01-22 05:39

The Random class is not set up for one instance to be used in multiple threads. Ofcourse, if you did this, likely you will increase the possibility of getting un-predictable and closer to random numbers. But since it is a pseudo-random generator, I cannot see why you would need to share an instance. Is there a more specific requirement?

查看更多
【Aperson】
7楼-- · 2019-01-22 05:49

Yes, Random is thread safe. the nextInt() method calls the protected next(int) method which uses AtomicLong seed, nextseed (atomic long) to generate a next seed. AtomicLong is used for thread-safety upon seed generation.

查看更多
登录 后发表回答