查看: 75|回复: 0

[教程] Java中并发下的ThreadlocalRandom的实现

[复制链接]

1

主题

0

回帖

0

积分

积极分子

金币
0
阅读权限
220
精华
0
威望
0
贡献
0
在线时间
0 小时
注册时间
2010-11-7
发表于 2026-1-13 09:19:16 | 显示全部楼层 |阅读模式

1. 背景

在看同事写的代码的时候发现代码里有很多像:

如果我们想要生成一个随机数,通常会使用Random类。但是在并发情况下Random生成随机数的性能并不是很理想,今天给大家介绍一下JUC包中的用于生成随机数的类–ThreadLocalRandom.(本文基于JDK1.8)

当然Random随机数也可以保证线程的安全,但是Random随机数生成是和种子seed有关,而为了保证线程安全性,Random通过CAS机制来保证线程安全性。

从next()方法中我们可以发现seed是通过自旋锁和CAS来进行修改值的。如果在高并发的场景下,那么可能会导致CAS不断失败,从而导致不断自旋,这样就可能会导致服务器CPU过高。我们可以看一下next的实现:

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

2.为什么要用ThreadLocalRandom

ThreadLocalRandom是ThreadLocal和Random类的组合,它与当前线程隔离。因此,它通过简单地避免对Random对象的任何并发访问,在多线程环境中实现了更好的性能。

一个线程获得的随机数不受另一个线程的影响,而java.util.Random全局提供随机数。

此外,与Random 不同,ThreadLocalRandom不支持显式设置种子。相反,它会覆盖从Random继承的setSeed(long seed)方法,以便在调用时始终抛出UnsupportedOperationException。

现在让我们看一下生成随机int,long和double值的一些方法。

根据Oracle文档,我们只需要调用ThreadLocalRandom.current()方法,它将返回当前线程的ThreadLocalRandom实例。然后,我们可以通过调用类的可用实例方法来生成随机值。

int unboundedRandomValue = ThreadLocalRandom.current().nextInt());

上面的代码可以生成一个没有任何边界的随机int值

int boundedRandomValue = ThreadLocalRandom.current().nextInt(0, 100);

这是一个生成0到100之间的随机int值的示例,值得注意的是:包含下限0,不包含上限100

同样我们也可以与上面示例中所示类似的方式调用nextLong()和nextDouble()方法来生成long和double的随机值。

Java 8还添加了nextGaussian()方法来生成下一个正态分布的值,其值与生成器序列的值相差 0.0和1.0。

与Random类一样,我们也可以使用doubles(),ints()和longs()方法生成随机值流。

到此这篇关于Java中并发下的ThreadlocalRandom的文章就介绍到这了,更多相关Java 并发ThreadlocalRandom内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!

您可能感兴趣的文章:
  • java.util.Random和concurrent.ThreadLocalRandom使用对比
  • Java中的Random和ThreadLocalRandom详细解析
  • Java生成随机数之Random与ThreadLocalRandom性能比较详解
  • Java并发编程ThreadLocalRandom类详解
  • java并发高的情况下用ThreadLocalRandom来生成随机数
  • java中ThreadLocalRandom的使用详解
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关侵权、举报、投诉及建议等,请发 E-mail:qiongdian@foxmail.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部