Random & ThreadLocalRandom 区别

Dcr 1年前 ⋅ 896 阅读

Random使用最广泛的随机数生成工具,即使Math.random()的底层也是使用Random实现

public static double random() {
        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
    }

接下来看看Random的源码解析

/**
 *源码版本:JDK 11
 */
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));
    }

根据以上源码可以看出,在使用oldseed获取nextseed的时候,如果是多线程操作,则同一时刻只会有一个线程CAS成功,其他失败的线程会通过自旋等待获取nextseed,因此会有一定的性能消耗.

这也就是为什么JDK1.7会引入ThreadLocalRandom的原因了,主要解决多线程情况下Random的执行效率问题.

ThreadLocalRandom:
ThreadLocalRandom继承于Random类

ThreadLocalRandom的源码解析:

/**
 * 源码版本:JDK 11
 */
final long nextSeed() {
        Thread t; long r; // read and update per-thread seed
        //把当前线程作为参数生成nextseed
        UNSAFE.putLong(t = Thread.currentThread(), SEED,
                       r = UNSAFE.getLong(t, SEED) + GAMMA);
        return r;
    }

从上述源码看出,ThreadLocalRandom并不是像Thread那样使用CAS喝自旋来获取nextseed,而是在每个线程使用线程变量存储自己的oldseed和生成nextseed,因此可以避免多线程竞争和自旋等待的时间,所以在多线程环境下性能更高.

ThreadLocalRandom注意事项
多线程不能共享一个ThreadLocalRandom对象,否则会造成生成的随机数都相同

全部评论: 0

    我有话说: