ThreadLocalRandom更适合高并发,因为它为每个线程提供独立实例,避免共享状态和CAS竞争,无锁且性能优于Random;使用current()获取线程本地实例,不可缓存或跨线程复用,不支持自定义种子且非加密安全。

在高并发场景下,用 java.util.Random 会产生竞争(因为内部使用 AtomicLong 更新种子),而 ThreadLocalRandom 是专为多线程设计的轻量级随机数生成器——它每个线程持有一份独立实例,无锁、无竞争,性能更好。
为什么 ThreadLocalRandom 更适合高并发
ThreadLocalRandom 不是通过 new 创建,而是绑定在线程本地(ThreadLocal)上,每次调用 current() 都返回当前线程专属的实例。它避免了共享状态和 CAS 操作,天然线程安全,开销远低于 Random 或 SecureRandom。
基本用法:获取并生成随机数
直接调用静态方法 ThreadLocalRandom.current() 获取当前线程的实例,再调用各类 nextInt()、nextLong()、nextDouble() 等:
-
ThreadLocalRandom.current().nextInt()—— 生成 int 范围内任意值 -
ThreadLocalRandom.current().nextInt(100)—— 生成 [0, 100) 的 int -
ThreadLocalRandom.current().nextInt(10, 20)—— 生成 [10, 20) 的 int(推荐区间写法) -
ThreadLocalRandom.current().nextLong(1_000L, 10_000L)—— 长整型区间 -
ThreadLocalRandom.current().nextDouble(0.0, 1.0)—— 双精度浮点区间
常见误区与注意事项
不要缓存 ThreadLocalRandom.current() 的返回值跨线程复用——它只属于当前线程;也不要在静态字段中保存它的引用(会破坏线程隔离性)。
立即学习“Java免费学习笔记(深入)”;
- ✅ 正确:每次需要时调用
ThreadLocalRandom.current().nextInt(...) - ❌ 错误:
private static final ThreadLocalRandom rnd = ThreadLocalRandom.current(); - ⚠️ 注意:
ThreadLocalRandom不支持设置自定义种子(没有setSeed()),不可用于需要可重现随机序列的场景(如测试固定输入) - ⚠️ 注意:它不是加密安全的,敏感用途(如 Token 生成)请用
SecureRandom
结合实际并发场景示例
比如在 ForkJoinPool 或 Web 请求线程池中生成请求 ID 或模拟延迟:
// 在 Spring Controller 或 Netty Handler 中
String requestId = String.format("req-%d-%d",
ThreadLocalRandom.current().nextLong(1000, 9999),
System.nanoTime() % 1000000
);
或在并行流中避免 Random 竞争:
list.parallelStream()
.map(item -> ThreadLocalRandom.current().nextBoolean() ? item.toUpperCase() : item)
.collect(Collectors.toList());
不复杂但容易忽略:只要涉及多线程随机数,优先选 ThreadLocalRandom,几乎零成本升级并发性能。



















