Java开发笔记(一百五十五)生成随机数的几种途径

随机数生成是一个常见的业务场景,比如摇号、抽奖等等都需要随机数。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开发笔记(序)章节目录

相关推荐
月明长歌13 小时前
【码道初阶】Leetcode138:随机链表的复制:用 HashMap 做深拷贝的标准解法
java·数据结构·算法·leetcode·链表·哈希算法
.简.简.单.单.13 小时前
Design Patterns In Modern C++ 中文版翻译 第八章 组合
java·c++·设计模式
七夜zippoe13 小时前
Spring MVC请求处理流程源码分析与DispatcherServlet核心逻辑
java·spring·mvc·过滤器·拦截器
笙枫13 小时前
Agent 进阶设计:状态管理、中间件与多Agent协作
java·服务器·python·ai·中间件
有趣灵魂13 小时前
Java-根据HTTP链接读取文件转换为base64
java·开发语言·http
YIN_尹13 小时前
CANN开源仓Catlass模板库核心能力与编程实战
java·开源·dubbo
华如锦13 小时前
微调—— LlamaFactory工具:使用WebUI微调
java·人工智能·python·ai
武子康14 小时前
Java-215 RocketMQ 消费模式:Push vs Pull 的本质、长轮询机制与 Offset/积压调优要
java·大数据·分布式·消息队列·rocketmq·java-rocketmq·mq
侧耳倾听11114 小时前
分布式ID之雪花算法
java·分布式
大叔_爱编程14 小时前
基于人脸识别的互联网课堂考勤系统-springboot
java·spring boot·毕业设计·人脸识别·源码·课程设计·课堂考勤系统