javamultithreadingperformanceconcurrencycontention

Contention in concurrent use of java.util.Random


Oracle Java documentation says:

Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.

What might be the reason behind poor performance?


Solution

  • Internally, java.util.Random keeps an AtomicLong with the current seed, and whenever a new random number is requested, there is contention in updating the seed.

    From the implementation of java.util.Random:

    protected int next(int bits) {
        long oldseed, nextseed;
        AtomicLong seed = this.seed;
        do {
            oldseed = seed.get();
            nextseed = (oldseed * multiplier + addend) & mask;
        } while (!seed.compareAndSet(oldseed, nextseed));
        return (int)(nextseed >>> (48 - bits));
    }
    

    On the other hand, ThreadLocalRandom ensures that the seed is updated without facing any contention, by having one seed per thread.