优先用ThreadLocalRandom,因其为每线程独享种子、无锁高效;Random仅适用于需可重现序列的场景,如单元测试、固定种子游戏关卡。
多线程环境下优先用 ThreadLocalRandom,单线程或需可重现序列时才用 Random。
为什么 ThreadLocalRandom 在并发场景下更安全
Random 内部用一个共享的 atomicLong(通过 compareAndSet 更新种子),高并发时大量线程争抢同一 CAS 操作,导致自旋重试、吞吐骤降;ThreadLocalRandom 为每个线程维护独立种子和算法状态,完全无锁。
常见错误现象:Random 在压测中 CPU 飙高但吞吐上不去,jstack 显示大量线程卡在 Random.next(int) 的 CAS 循环里。
- 适用场景:Web 请求中生成订单号、验证码、采样阈值等——只要不跨线程复用实例
- 不能直接 new:
ThreadLocalRandom.current()是唯一正确入口,它会自动初始化线程私有实例 - 不支持设置种子(
setSeed(long)),所以无法重现随机序列
Random 唯一不可替代的使用场景
当需要「可重现」的随机行为时,Random 是必须的。比如单元测试中验证概率逻辑、游戏关卡种子固定、算法调试需要稳定输出。
立即学习“Java免费学习笔记(深入)”;
注意:Random 实例本身是线程安全的,但「安全」不等于「高效」——它的同步开销在并发下会成为瓶颈。