random.nextint(n)生成[0,n)范围整数,故nextint(10)得0–9;要1–10需+1;多线程应选threadlocalrandom;securerandom用于安全场景而非提升随机性。

用 Random 生成整数时,为什么总拿到 0?
因为没传对范围参数——nextInt(n) 返回的是 [0, n)(左闭右开),不是 [1, n]。想生成 1–10 的随机整数,得写 random.nextInt(10) + 1。
- 常见错误:直接用
nextInt(10)当作「1 到 10」,结果永远拿不到 10,最小值还是 0 - 如果需要指定上下界(比如 [5, 15]),正确写法是
random.nextInt(15 - 5 + 1) + 5 -
nextInt()不带参版本返回 int 全范围(-2³¹ 到 2³¹−1),极少用,容易溢出或逻辑错位
并发环境下用 Random 安全吗?
不安全。多个线程共用同一个 Random 实例时,next() 内部的原子操作可能被干扰,导致重复值、卡顿甚至伪随机性崩塌。
- 单线程场景下,复用一个
Random实例没问题,性能略优于每次 new - 多线程场景优先用
ThreadLocalRandom:调用ThreadLocalRandom.current().nextInt(1, 11),无锁、无竞争、初始化开销低 - 别用
new Random(System.currentTimeMillis())在循环里反复初始化——毫秒级时间戳在高并发下极易重复,导致大量相同种子和相同随机序列
SecureRandom 真的比 Random “更随机”?
不是“更随机”,是“不可预测”。它用操作系统熵源(如 /dev/urandom)做种子,适合密码、token、密钥等安全敏感场景;但代价是慢、阻塞风险(尤其在熵不足的容器环境)、无法复现。
- 普通业务逻辑(抽奖、测试数据、UI 动画偏移)完全不需要
SecureRandom,用Random或ThreadLocalRandom就够了 -
SecureRandom.getInstance("SHA1PRNG")在某些 JDK 版本中默认依赖阻塞式熵源,Docker 容器里可能卡住几秒,建议显式指定"NativePRNGNonBlocking"(JDK 8u161+) - 别为了“显得安全”而滥用——它不能提升算法分布质量,只防种子被猜解
Lambda 里怎么简洁生成随机数?
Java 8+ 可配合 IntStream 快速生成一批随机整数,但要注意边界语义和是否需要去重。
立即学习“Java免费学习笔记(深入)”;
- 生成 5 个 1–100 的随机数:
ThreadLocalRandom.current().ints(5, 1, 101).toArray()(注意上界是 101) - 要唯一值?加
.distinct(),但得控制好数量,否则可能无限等待 - 别用
Random::nextInt方法引用直接传给Stream.generate()——它没状态,所有元素都用同一个种子,结果全一样
真正难的不是选哪个类,而是想清楚你要的是「快」「可重现」「线程安全」还是「抗预测」——这四个目标彼此冲突,没法靠一个工具全满足。










