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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…