AI工具人
提示词工程师

java.util.Random和concurrent.ThreadLocalRandom对比

  最近工作中遇到了一个需求,需要以一定的概率过滤掉一部分的流量,想想只能用Random了,因为是在多线程环境下,我还特意确认了下Random在多线程是否能正常运行,Random的实现也比较简单,初始化的时候用当前的事件来初始化一个随机数种子,然后每次取值的时候用这个种子与有些MagicNumber运算,并更新种子。最核心的就是这个next的函数,不管你是调用了nextDouble还是nextInt还是nextBoolean,Random底层都是调这个next(int bits)。

    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));
    }

  为了保证多线程下每次生成随机数都是用的不同,next()得保证seed的更新是原子操作,所以用了AtomicLong的compareAndSet(),该方法底层调用了sum.misc.Unsafe的compareAndSwapLong(),也就是大家常听到的CAS, 这是一个native方法,它能保证原子更新一个数。
  

  既然Random满足我的需求,又能在多线程下正常运行,所以我直接用了random,后来在codeReview中,同事提出用concurrent.ThreadLocalRandom来替代Random。我脑子里立马冒出一个问题,既然random是线程安全的,为什么concurrent包里还要实现一个random。在oracle的jdk文档里发现这样一句话

赞(1) 打赏
未经允许不得转载:XINDOO » java.util.Random和concurrent.ThreadLocalRandom对比
描述文字

评论 抢沙发

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫