Java中随机数生成的多种方式

 更新时间:2026年02月28日 09:29:40   作者:yingjuxia.com  
本文详细介绍了Java中的随机数生成方式,包括Math.random()、Random、ThreadLocalRandom、SecureRandom和SplittableRandom,并提供了每种方式的适用场景和最佳实践,需要的朋友可以参考下

Java 中生成随机数是日常开发中最常见的需求之一:从简单的抽奖、验证码,到游戏、模拟、测试数据,再到安全敏感的密钥、token 生成,随机数无处不在。

但很多人只知道 Math.random(),其实 Java 提供了多种随机数生成方式,每种适用场景完全不同,用错会导致性能爆炸、线程安全问题,甚至安全漏洞!

本文从零基础讲到精通,带你彻底搞懂 Java 随机数的全部玩法。

一、Java 随机数家族全景图(推荐收藏)

方式包路径随机类型线程安全性能(并发下)安全性推荐场景JDK 版本
Math.random()java.lang伪随机中等非常简单的单线程场景1.0
java.util.Randomjava.util伪随机是(但慢)单线程或低并发普通随机1.0
ThreadLocalRandomjava.util.concurrent伪随机每个线程独立极高高并发普通随机(目前最推荐的普通场景1.7
SecureRandomjava.security加密安全随机较低高(加密级)密码、密钥、token、nonce、验证码等安全场景1.1
SplittableRandomjava.util伪随机非线程安全并行计算、流式处理(ForkJoinPool 等)1.8

二、零基础快速上手(最常用的几种写法)

1. 最简单的方式(入门必会)

// [0.0, 1.0) 之间的 double
double d = Math.random();

// 0 ~ 9 的整数
int num = (int) (Math.random() * 10);

// 更推荐:使用 Random(范围更清晰)
Random random = new Random();
int num2 = random.nextInt(10);         // [0, 10)
int num3 = random.nextInt(5, 15);      // [5, 15)   JDK 17+ 才支持

2. 生成指定范围的整数(最常用写法)

// 通用写法:min(包含) ~ max(不包含)
public static int nextInt(int min, int max) {
    return min + new Random().nextInt(max - min);
}

// 更高效(推荐)
ThreadLocalRandom.current().nextInt(min, max);

三、三大主流随机数生成器详细对比与源码级讲解

1. Random(最经典,但别乱用)

Random r = new Random();                // 默认种子 = 当前时间毫秒
// 或
Random r = new Random(123456789L);      // 指定种子 → 可复现

r.nextInt();        // int 全范围
r.nextInt(100);     // [0,100)
r.nextBoolean();
r.nextDouble();     // [0.0, 1.0)
r.nextGaussian();   // 高斯分布(正态分布)

缺点

  • 多线程下内部用 CAS + synchronized,竞争激烈时性能很差
  • 种子可预测(尤其是用时间戳),安全性低

2. ThreadLocalRandom(高并发首选,性能之王)

// 正确用法(不要 new)
ThreadLocalRandom random = ThreadLocalRandom.current();

// 用法和 Random 几乎一样
int i = random.nextInt(100);
int range = random.nextInt(10, 50);   // [10,50)
long l = random.nextLong(1_000_000);
double d = random.nextDouble(0.0, 1.0);

为什么比 Random 快很多?

  • 每个线程拥有独立的随机数生成器(ThreadLocal 思想)
  • 无锁、无竞争
  • 官方推荐:在高并发场景下替换 Random,性能可提升 3~10 倍

注意:不支持手动设置种子(设计上故意禁止),不可复现。

3. SecureRandom(安全场景必须用)

// 最常用写法
SecureRandom sr = new SecureRandom();           // 默认强随机

// 指定算法(常见)
SecureRandom sr2 = SecureRandom.getInstance("NativePRNG");
SecureRandom sr3 = SecureRandom.getInstanceStrong();  // 最安全(但最慢)

byte[] token = new byte[32];
sr.nextBytes(token);   // 填充 32 字节安全随机数

int code = 100_000 + sr.nextInt(900_000);   // 6位验证码

特点

  • 种子来自操作系统熵池(鼠标移动、键盘敲击、硬件中断等)
  • 不可预测,不可复现
  • 用于:session id、CSRF token、盐、密钥、UUID v4 等

性能:比 Random 慢 10~100 倍,但安全第一。

四、常见场景最佳实践(直接抄就行)

普通游戏、测试数据、模拟、抽奖
ThreadLocalRandom.current()

Web 后台普通随机(日志、分配 id 等)
ThreadLocalRandom

验证码、短信码、找回密码 token
SecureRandom

生成安全密钥、nonce、签名盐
SecureRandom.getInstanceStrong()NativePRNG

想要结果可复现(调试、测试用例)
new Random(固定种子)

并行流或 ForkJoinPool 大规模并行计算
SplittableRandom

五、经典误区与面试高频问题

  • Math.random() 底层就是 new Random(),多线程下性能差
  • Random 是线程安全的,但并发性能极差
  • ThreadLocalRandom 不能 new,只能用 current()
  • SecureRandom 不要在循环里反复 new(很慢),复用一个实例
  • 永远不要用 Random 生成密码/密钥/验证码(可被预测攻击)
  • JDK 17+ 推荐:RandomGenerator 接口统一 API(未来趋势)

六、终极总结一句话

  • 普通随机 → ThreadLocalRandom(性能最高)
  • 安全随机 → SecureRandom(安全第一)
  • 想要可复现 → new Random(种子)
  • 简单写 → Math.random()(但别在高并发用)

掌握这三大家族,基本覆盖 99% 的随机数需求。

到此这篇关于Java中随机数生成的多种方式的文章就介绍到这了,更多相关Java随机数生成方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现在图片中添加文字水印的示例代码

    Java实现在图片中添加文字水印的示例代码

    本文介绍了一个使用Java实现的图片水印工具,该工具能够读取指定路径的图片,在图片上添加文字水印,并将带有水印的图片保存到指定路径,感兴趣的小伙伴可以了解下
    2026-05-05
  • Java实现人机猜拳游戏

    Java实现人机猜拳游戏

    这篇文章主要为大家详细介绍了Java实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • springboot使用单元测试实战

    springboot使用单元测试实战

    这篇文章主要介绍了springboot使用单元测试实战,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • Java8与Scala中的Lambda表达式深入讲解

    Java8与Scala中的Lambda表达式深入讲解

    这篇文章主要给大家介绍了关于Java8与Scala中Lambda表达式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • Java中的volatile关键字解析

    Java中的volatile关键字解析

    这篇文章主要介绍了Java中的volatile关键字解析,Java内存模型规定了所有的变量都存储在主内存中,每个线程都有自己的工作内存,线程的工作内存保存了该线程使用到的变量的是主内存副本的拷贝,需要的朋友可以参考下
    2023-11-11
  • Java并发编程中高频异常的原因,场景与解决方案全解析

    Java并发编程中高频异常的原因,场景与解决方案全解析

    在Java并发编程中,异常处理是保障程序稳定性的核心环节,本文将深度解析4类高频并发异常的产生原因、典型场景,并给出可落地的解决方案,帮你彻底避开这些坑
    2026-03-03
  • SpringBoot中获取微信用户信息的方法

    SpringBoot中获取微信用户信息的方法

    这篇文章主要介绍了SpringBoot中获取微信用户信息的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Java实现对象转CSV格式

    Java实现对象转CSV格式

    CSV是一种逗号分隔值格式的文件,一般用来存储数据的纯文本格式文件。Java对象转CSV,有现成的工具包,commons-lang3 的ReflectionToStringBuilder 就可以简单的解决的对象转CSV,快跟随小编一起学习一下吧
    2022-06-06
  • 解决IDEA2020.1.2IDEA打不开的问题(最新分享)

    解决IDEA2020.1.2IDEA打不开的问题(最新分享)

    由于idea安装多了某个jar,点击出现读条后闪退情况,接下来通过本文给大家分享解决IDEA2020.1.2IDEA打不开的问题,非常不错,具有一定的参考借鉴价值,感兴趣的朋友跟随小编一起看看吧
    2020-07-07
  • Flink DataStream基础框架源码分析

    Flink DataStream基础框架源码分析

    这篇文章主要为大家介绍了Flink DataStream基础框架源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12

最新评论