Is Random class thread safe?

前端 未结 8 927
臣服心动
臣服心动 2020-12-13 11:53

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条回答
  • 2020-12-13 12:04

    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());
        }
    };
    
    0 讨论(0)
  • 2020-12-13 12:05

    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?

    0 讨论(0)
  • 2020-12-13 12:06

    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.

    0 讨论(0)
  • 2020-12-13 12:09

    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.

    0 讨论(0)
  • 2020-12-13 12:12

    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.

    0 讨论(0)
  • 2020-12-13 12:19

    It is thread safe, although it wasn't always.

    See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6362070 for more details.

    0 讨论(0)
提交回复
热议问题