threadlocalrandom性能优于random,因其为每线程分配独立实例,避免cas竞争;random因共享seed导致多线程下自旋重试、吞吐非线性下降。

在高并发场景下,ThreadLocalRandom 的性能显著优于 Random,主要因为它避免了多线程竞争同一随机数生成器的状态,无需同步开销。
为什么 Random 在并发下性能差?
Random 内部维护一个共享的原子状态(seed),每次生成随机数都要通过 CAS 更新该状态。在多线程频繁调用时,大量线程会因 CAS 失败而自旋重试,造成显著的 CPU 浪费和吞吐下降。
- 所有线程共用同一个 seed 变量
- next()、nextInt() 等方法内部调用
UNSAFE.compareAndSwapLong保证原子性 - 线程越多,CAS 冲突越频繁,性能呈非线性下降
ThreadLocalRandom 如何解决这个问题?
它为每个线程分配独立的随机数生成器实例,初始化时基于当前线程的 probe 值和系统纳秒时间生成专属 seed,后续操作完全无共享、无同步。
- 首次调用
current()时才懒加载本线程专属实例 - 不继承 Random 类,但 API 兼容(如 nextInt()、nextDouble())
- 没有全局状态争用,吞吐量随线程数近似线性增长
实际压测表现差异(参考 JMH 结果)
在 16 线程并发调用 nextInt(100) 的典型测试中:
- Random 吞吐量约为 80–120 Mops/s(百万次/秒),且线程数增加后明显下降
- ThreadLocalRandom 吞吐量可达 350–450 Mops/s,扩展性良好
- GC 压力也更低,因为不频繁创建临时对象或触发锁膨胀
使用建议
只要在多线程环境生成随机数,应优先使用 ThreadLocalRandom:
- 替换
new Random()→ 改用ThreadLocalRandom.current() - 避免在单线程中反复调用
current(),可复用返回的实例(它是线程安全且线程绑定的) - 不需要自己管理种子或初始化逻辑,框架已处理好隔离与初始化时机
- 注意:它不能用于需要可重现序列的场景(如测试固定 seed),此时仍需 Random 或 SecureRandom










