随机数生成是一个常见的业务场景,比如摇号、抽奖等等都需要随机数。Java代码主要有三种随机数的生成方式,包括Math.random、Random、ThreadLocalRandom等,分别说明如下:

1、Math.random

Java代码调用Math.random()会返回一个大于等于0.0且小于1.0的双精度类型随机数,即取值区间落在[0,1)。可见该方式获取的随机数是个小数,如果业务需要随机整数的话,就得把随机小数放大若干倍后再取整,使得Math.random用起来多有不便。

2、Random

查看Math.random的源码,发现该函数实际调用了randomNumberGenerator的nextDouble方法:

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

查找randomNumberGenerator发现该对象为Random类型,且其实例由new Random()获得:

private static final class RandomNumberGeneratorHolder {
static final Random randomNumberGenerator = new Random();
}

可见Math.random的随机数来自于Random。除了nextDouble方法,Random还提供了nextFloat、nextInt、nextLong等方法用于生成对应类型的随机数。就生成随机整数而言,还能通过nextInt(**)获取指定范围的随机整数。例如以下代码生成的随机整数取值区间为[0,100):

Random random = new Random();
int result = random.nextInt(100);

3、ThreadLocalRandom

虽然在多数场合Random已经够用了,但在多线程情况下,各线程会竞争同一个随机种子,导致有概率因抢占失败而自旋重试。
为了解决Random在多线程场合出现性能降低的问题,Java提供了保证线程安全的ThreadLocalRandom。在多线程情况下,ThreadLocalRandom会给每个线程维护单独的随机种子,这样各线程各自使用自己的随机种子,就避免了抢占失败的问题了。
ThreadLocalRandom的用法很简单,仅需以下两行代码即可获得取值区间为[0,100)的随机整数:

ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
threadLocalRandom.nextInt(100);

更多Java技术文章参见《Java开发笔记(序)章节目录

Java开发笔记(一百五十五)生成随机数的几种途径的更多相关文章

  1. Java开发笔记(六十五)集合:HashSet和TreeSet

    对于相同类型的一组数据,虽然Java已经提供了数组加以表达,但是数组的结构实在太简单了,第一它无法直接添加新元素,第二它只能按照线性排列,故而数组用于基本的操作倒还凑合,若要用于复杂的处理就无法胜任了 ...

  2. Java开发笔记(八十五)通过字符流读写文件

    前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...

  3. Java开发笔记(二十五)方法的输入参数

    前面通过main方法介绍了方法的定义形式,对于方法的输入参数来说,还有几个值得注意的地方,接下来分别对输入参数的几种用法进行阐述.一个方法可以有输入参数,也可以没有输入参数,倘若无需输入参数,则方法定 ...

  4. Java开发笔记(三十五)字符串格式化

    前面介绍了字符串变量的四种赋值方式,对于简单的赋值来说完全够用了,即便是两个字符串拼接,也只需通过加号把两个目标串连起来即可.但对于复杂的赋值来说就麻烦了,假设现在需要拼接一个很长的字符串,字符串内部 ...

  5. Java开发笔记(四十五)成员属性与成员方法

    前面介绍了许多数据类型,除了基本类型如整型int.双精度型double.布尔型boolean之外,还有高级一些的如包装整型Integer.字符串类型String.本地日期类型LocalDate等等,那 ...

  6. Java开发笔记(七十五)异常的处理:扔出与捕捉

    前面介绍的几种异常(不包含错误),编码的时候没认真看还发现不了,直到程序运行到特定的代码跑不下去了,程序员才会恍然大悟:原来这里的代码逻辑有问题.像这些在运行的时候才暴露出来的异常,又被称作“运行时异 ...

  7. Java开发笔记(七十)Java8新增的几种泛型接口

    由于泛型存在某种不确定的类型,因此很少直接运用于拿来即用的泛型类,它更经常以泛型接口的面目出现.例如几种基本的容器类型Set.Map.List都被定义为接口interface,像HashSet.Tre ...

  8. OpenCV开发笔记(六十五):红胖子8分钟带你深入了解ORB特征点(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  9. Java开发笔记(八十二)注解的基本单元——元注解

    Java的注解非但是一种标记,还是一种特殊的类型,并且拥有专门的类型定义.前面介绍的五种内置注解,都可以找到对应的类型定义代码,例如查看注解@Override的源码,发现它的代码定义是下面这样的: @ ...

  10. Java开发笔记(三十八)利用正则表达式校验字符串

    前面多次提到了正则串.正则表达式,那么正则表达式究竟是符合什么定义的字符串呢?正则表达式是编程语言处理字符串格式的一种逻辑式子,它利用若干保留字符定义了形形色色的匹配规则,从而通过一个式子来覆盖满足了 ...

随机推荐

  1. mongo db集群故障选举分析

    转载请注明出处: 一.MongoDB集群基础架构 1. 副本集(Replica Set)核心原理 节点角色: Primary:唯一可写节点,处理所有写操作和默认读请求 Secondary:异步复制Pr ...

  2. IOC 中 bean 标签

  3. 借助 QT 的反射机制实现数据类的序列化

    在 C++ 工程中经常需要使用数据类,并对数据类进行存储.打印.调试等操作.由于数据类中有大量数据字段,每次都编写存储或输出数据内容,工作重复量太大.C++ 不支持用户自定义的注解,所以没办法使用类似 ...

  4. excel使用VBA连接access

    需要的引用: 下面的代码涉及excel对access数据库的增删改查,可以按照需要查找使用 1 '远程链接模块 2 Option Explicit 3 Dim con As New ADODB.Con ...

  5. Nim 概念 Concept 对性能的影响

    Nim 概念 Concept 对性能的影响 继上一篇文章<C# 泛型编译特性对性能的影响>后,我又研究了 Nim 语言相关的设计,由于 Nim 语言与 C# 语言有些差异,比如Nim 没有 ...

  6. CTF你真的懂PHP吗--PHP代码审计

    http://ctf5.shiyanbar.com/web/PHP/index.php 就是一个纯代码审计 访问.txt地址撸一把源码 进行分析 <?php $info = "&quo ...

  7. Next App Router 模式下,如何同步服务端 Redux 初始状态?

    大家的阅读是我发帖的动力,本文首发于我的博客:deerblog.gu-nami.com/,欢迎大家来玩,转载请注明出处喵. 前言 Next.js 是一个广受欢迎的 React 服务端渲染(Server ...

  8. 深挖diff算法:揭开代码版本控制神器的神秘面纱

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  9. 异步之舞:FastAPI与MongoDB的深度协奏

    title: 异步之舞:FastAPI与MongoDB的深度协奏 date: 2025/05/18 19:09:08 updated: 2025/05/18 19:09:08 author: cmdr ...

  10. Springboot 之JPA查询报错

    在 CatDao中添加自定义查询方法后,启动报错 1 2019-06-11 11:06:13.874 INFO 14700 --- [ restartedMain] org.hibernate.Ver ...