一、核心类概览
类/方法 | 适用场景 | 线程安全 | 特点 |
---|---|---|---|
Math.random() |
简单场景 | ✅ 安全 | 快速但功能有限 |
java.util.Random |
通用场景 | ❌ 不安全 | 功能丰富,可子类化 |
ThreadLocalRandom |
多线程高并发 | ✅ 安全 | 高性能,推荐多线程使用 |
SecureRandom |
安全敏感场景 | ✅ 安全 | 密码学安全,速度慢 |
SplittableRandom |
并行流/函数式 | ✅ 安全 | Java 8+,适合并行计算 |
二、方法详解
1. Math.random()
—— 最简单方式
// 生成 [0.0, 1.0) 范围内的 double 值
double random = Math.random();
// 生成 [min, max) 范围内的整数
int min = 1, max = 10;
int randomInt = (int)(Math.random() * (max - min)) + min;
// 示例:生成 1-6 的骰子点数
int dice = (int)(Math.random() * 6) + 1;
✅ 优点:语法简单,无需导入。
❌ 缺点:只能生成double
,范围固定,无法自定义种子。
2. java.util.Random
—— 通用随机数生成器
import java.util.Random;
Random random = new Random(); // 使用系统时间作为种子
// 生成各种类型随机数
int randInt = random.nextInt(); // 所有 int 范围
int randInRange = random.nextInt(100); // [0, 100)
long randLong = random.nextLong(); // 所有 long 范围
boolean randBool = random.nextBoolean(); // true/false
float randFloat = random.nextFloat(); // [0.0, 1.0)
double randDouble = random.nextDouble(); // [0.0, 1.0)
// 生成指定范围的整数 [min, max]
int min = 10, max = 50;
int result = random.nextInt(max - min + 1) + min;
// 使用自定义种子(可重现序列)
Random seeded = new Random(12345L);
System.out.println(seeded.nextInt()); // 每次运行结果相同
✅ 优点:类型丰富,支持种子,可预测序列。
❌ 注意:非线程安全,多线程高并发时性能下降。
3. ThreadLocalRandom
—— 高性能并发随机数(推荐多线程)
import java.util.concurrent.ThreadLocalRandom;
// 静态方法调用,无需实例化
ThreadLocalRandom random = ThreadLocalRandom.current();
// 生成随机数
int randInt = random.nextInt(); // [Integer.MIN_VALUE, Integer.MAX_VALUE)
int randInRange = random.nextInt(1, 101); // [1, 101) → [1,100]
long randLong = random.nextLong(1000L, 2000L); // [1000, 2000)
double randDouble = random.nextDouble(0.0, 1.0); // [0.0, 1.0)
// 示例:生成 1-6 的骰子
int dice = random.nextInt(1, 7);
✅ 优点:
- 线程安全且无锁竞争
- 性能极高,多线程场景首选
- API 与
Random
兼容
📌 官方推荐:在多线程环境中替代
Random
。
4. SecureRandom
—— 密码学安全随机数
import java.security.SecureRandom;
SecureRandom secureRandom = new SecureRandom();
// 生成安全随机数
byte[] bytes = new byte[16];
secureRandom.nextBytes(bytes); // 填充随机字节
int randInt = secureRandom.nextInt(100); // [0, 100)
String token = secureRandom.ints(8, 48, 123) // 生成8位数字+字母token
.filter(i -> (i < 58 || i > 64) && (i < 91 || i > 96)) // 过滤特殊字符
.collect(StringBuilder::new,
StringBuilder::appendCodePoint,
StringBuilder::append)
.toString();
✅ 优点:
- 密码学安全,不可预测
- 适合生成密钥、令牌、盐值等
❌ 缺点:速度慢,不要用于普通随机需求。
5. SplittableRandom
—— 并行流友好(Java 8+)
import java.util.SplittableRandom;
SplittableRandom splitRandom = new SplittableRandom();
// 生成随机数
int randInt = splitRandom.nextInt(1, 101); // [1, 101)
long randLong = splitRandom.nextLong(100, 200); // [100, 200)
double[] doubles = splitRandom.doubles(10).toArray(); // 生成10个随机double
// 与流结合使用
int[] randomArray = splitRandom.ints(100, 1, 1000).toArray(); // 100个1-999的随机数
// 并行流中使用
long count = splitRandom.longs(1_000_000)
.parallel()
.filter(x -> x % 2 == 0)
.count();
✅ 优点:
- 专为并行计算设计
- 支持
split()
生成新实例- 性能优秀
📌 适用场景:大数据生成、并行流、函数式编程。
三、生成特定分布的随机数
1. 正态分布(高斯分布)
Random random = new Random();
double gaussian = random.nextGaussian(); // 均值0.0,标准差1.0
// 转换为均值 μ,标准差 σ
double mu = 50.0, sigma = 10.0;
double normal = mu + sigma * gaussian;
2. 随机布尔值(按概率)
Random random = new Random();
double probability = 0.7; // 70% 概率为 true
boolean likelyTrue = random.nextDouble() < probability;
3. 随机选择数组元素
String[] colors = {"红", "绿", "蓝", "黄"};
Random random = new Random();
String randomColor = colors[random.nextInt(colors.length)];
四、最佳实践与注意事项
✅ 推荐用法
场景 | 推荐类 |
---|---|
简单单线程 | Math.random() 或 Random |
多线程高并发 | ThreadLocalRandom ✅ 首选 |
安全敏感(密码、token) | SecureRandom |
并行流/大数据 | SplittableRandom |
❌ 常见错误
在多线程中共享
Random
实例// 错误!性能差 private static Random sharedRandom = new Random(); // 正确:使用 ThreadLocalRandom ThreadLocalRandom.current().nextInt();
用
Math.random()
生成整数时类型转换错误// 错误:可能越界 int bad = (int) Math.random() * 100; // 正确 int good = (int) (Math.random() * 100);
SecureRandom
用于普通场景// 不推荐:太慢 // SecureRandom 仅用于安全关键场景
忽略种子的可重现性
// 调试/测试时可使用固定种子 Random debugRandom = new Random(42L); // 每次结果相同
五、性能对比(简要)
类 | 单线程性能 | 多线程性能 | 安全性 |
---|---|---|---|
Math.random() |
中等 | 中等 | 一般 |
Random |
高 | 低 ❌ | 一般 |
ThreadLocalRandom |
高 | 极高 ✅ | 一般 |
SecureRandom |
低 ❌ | 低 ❌ | 高 ✅ |
SplittableRandom |
高 | 高 | 一般 |
六、总结
需求 | 推荐方案 |
---|---|
快速生成一个 0-1 小数 | Math.random() |
通用随机整数/布尔值 | ThreadLocalRandom.current().nextInt() ✅ |
多线程环境 | ThreadLocalRandom ✅ |
生成密码、令牌 | SecureRandom ✅ |
并行流、大数据生成 | SplittableRandom ✅ |
可重现序列(测试) | new Random(seed) |
✅ 终极建议:
- 日常开发优先使用
ThreadLocalRandom
- 安全相关必须使用
SecureRandom
- 避免在高并发中共享
Random
实例
掌握这些随机数生成方式,能让你的 Java 程序更高效、安全、健壮。