Java中并发下的ThreadlocalRandom的实现

 更新时间:2026年01月13日 09:19:16   作者:ZNineSun  
本文介绍了Java1.8中的ThreadLocalRandom类,它在并发环境下比Random类有更好的性能,下面就来详细的介绍一下如何使用,感兴趣的可以了解一下

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中static的用法及注意点

    java中static的用法及注意点

    在本篇文章里小编给大家整理的是一篇关于java中static的用法及注意点,有兴趣的朋友们可以学习下。
    2021-03-03
  • Java使用TCP实现在线聊天的示例代码

    Java使用TCP实现在线聊天的示例代码

    这篇文章主要介绍了Java使用TCP实现在线聊天的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • 基于mybatis-plus 时间字段比较

    基于mybatis-plus 时间字段比较

    这篇文章主要介绍了mybatis-plus 时间字段的比较,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • SpringBoot项目中自定义线程池的方法步骤

    SpringBoot项目中自定义线程池的方法步骤

    在Spring Boot项目中,合理配置和使用线程池对于提升应用程序性能、优化资源利用和保证系统稳定性至关重要,本文将详细介绍如何在Spring Boot中自定义线程池,包括配置方式、参数调优、使用方法和最佳实践,需要的朋友可以参考下
    2025-09-09
  • Java开发者必备10大数据工具和框架

    Java开发者必备10大数据工具和框架

    这篇文章主要为大家详细介绍了Java开发者必备10大数据工具和框架,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • mybatis模糊查询、分页和别名配置的方法

    mybatis模糊查询、分页和别名配置的方法

    这篇文章主要介绍了mybatis模糊查询、分页和别名配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 如何利用JAVA正则表达式轻松替换JSON中的大字段

    如何利用JAVA正则表达式轻松替换JSON中的大字段

    这篇文章主要给大家介绍了关于如何利用JAVA正则表达式轻松替换JSON中大字段的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Java中如何正确定义字符串

    Java中如何正确定义字符串

    这篇文章主要给大家介绍了关于Java中如何正确定义字符串的相关资料,在Java中定义一个字符串最简单的方法是用双引号把它包围起来,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • JAVA JNI原理详细介绍及简单实例代码

    JAVA JNI原理详细介绍及简单实例代码

    这篇文章主要介绍了JAVA JNI原理的相关资料,这里提供简单实例代码,需要的朋友可以参考下
    2016-12-12
  • 如何基于java向mysql数据库中存取图片

    如何基于java向mysql数据库中存取图片

    这篇文章主要介绍了如何基于java向mysql数据库中存取图片,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02

最新评论