random在高并发下因共享atomiclong种子导致cas频繁失败重试,性能低下;threadlocalrandom为每线程独享种子,无竞争,吞吐量达3500万次/秒以上。

在高并发场景下,Random 的 nextXXX() 方法内部会通过 CAS 更新共享的原子种子(seed),导致线程频繁争抢、重试,产生显著性能损耗。而 ThreadLocalRandom 为每个线程独立维护一个种子,完全避免了跨线程竞争,是更优选择。
为什么 Random 在并发下有性能瓶颈
Random 使用一个全局的 AtomicLong seed,每次生成随机数都要执行:
- CAS 更新种子值(可能失败重试)
- 基于旧种子计算新值和返回结果
- 高并发时大量线程卡在 CAS 自旋上,CPU 利用率虚高、吞吐下降
ThreadLocalRandom 的核心优势
它不依赖共享状态,而是:
- 首次调用时,为当前线程初始化专属种子(基于系统纳秒时间、线程 ID 等混合生成)
- 后续所有操作只读写本线程栈/线程局部变量,无同步开销
- 无需构造实例,直接用静态方法:
ThreadLocalRandom.current().nextInt()
正确使用方式与注意事项
替换非常简单,但需注意几个关键点:
- ❌ 不要缓存
ThreadLocalRandom.current()实例(比如赋值给字段或静态变量),它只对当前线程有效,且每次调用都确保线程本地状态已就绪 - ✅ 推荐写法:
int r = ThreadLocalRandom.current().nextInt(100);—— 每次都调用current() - ✅ 支持范围控制:
nextInt(10, 20)、nextDouble(0.0, 1.0)、nextLong(1L, 100L)等,语义清晰且安全 - ✅ 在 ForkJoinPool 或虚拟线程中同样高效,天然适配现代并发模型
实际效果对比(简要示意)
在 16 核机器、100 线程并发调用 nextInt() 的压测中:
-
Random吞吐约 800 万次/秒,CAS 失败率超 40% -
ThreadLocalRandom吞吐可达 3500 万次/秒以上,零同步开销
差距主要来自去中心化设计——没有锁,也没有 CAS,只有纯本地计算。










