Random线程安全但高并发下因CAS争抢导致性能瓶颈;ThreadLocalRandom为并发优化,每线程独立状态、无同步开销;SecureRandom安全优先,依赖系统熵源,适用于密钥等敏感场景。

Random:线程安全但有性能瓶颈
Random 类本身是线程安全的,内部用 AtomicLong 管理种子,每个方法调用都保证原子性。但它的问题在于——多个线程共用同一个实例时,会频繁争抢更新种子值,底层靠 CAS 自旋 实现,高并发下容易导致缓存行失效和吞吐量下降。
常见表现包括:
- 8线程共享一个 Random 实例,吞吐量反而低于单线程
- 生成验证码、会话ID等高频场景中,成为响应延迟的隐性瓶颈
- 虽不会出错,但性能损耗真实可见,尤其在 CPU 密集型服务中
ThreadLocalRandom:专为并发优化的设计
Java 7 引入的 ThreadLocalRandom 不是“加锁版 Random”,而是彻底放弃共享种子,让每个线程持有独立的随机数状态(通过 Thread 类的私有字段 threadLocalRandomSeed 等实现)。它不依赖 CAS,也没有同步开销。
使用要点很直接:
- 不 new 实例,统一调用 ThreadLocalRandom.current()
- 适用于大多数多线程业务场景,如负载均衡选节点、模拟请求延迟、分页随机偏移等
- 不能指定 seed,也不支持 setSeed —— 这是为线程隔离性做的取舍
SecureRandom:安全优先,性能让步
SecureRandom 的目标不是快,而是不可预测、抗重放、满足密码学要求。它会从操作系统采集熵源(如 /dev/urandom、硬件时钟抖动等),再经由 SHA 或 AES 等算法混合生成随机数。
这意味着:
- 线程安全,但初始化可能阻塞(尤其在熵不足的容器环境)
- 生成速度明显慢于前两者,不适合高频调用
- 必须用于敏感场景:JWT 密钥、AES 初始化向量、一次性令牌、密码盐值等
怎么选?看场景说话
不需要纠结“哪个最好”,关键匹配实际需求:
- 单线程或低并发工具类 → Random 足够,简单可靠
- Web 服务、消息处理、批任务等多线程通用逻辑 → ThreadLocalRandom 是默认推荐
- 涉及密钥、签名、认证、加密的环节 → 必须用 SecureRandom,别省这点开销
混淆风险提示:用 Random 生成 token 或 salt,等于把系统安全建立在可预测的线性序列上,实际已有不少漏洞案例源于此。

















