Java并发包中ThreadLocalRandom类原理剖析

本文剖析了Java并发包中ThreadLocalRandom类的工作原理。针对Random类在并发场景下的局限性,ThreadLocalRandom通过为每个线程维护独立的种子变量,确保了随机数生成的线程安全性。文章详细介绍了其current()方法和nextInt方法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java并发包中ThreadLocalRandom类原理剖析

一、Random类的局限性

Random类产生随机数的两个步骤

  • 根据老的种子生成新的种子
  • 根据新的种子计算新的随机数

在并发条件下,由于Random类在产生新种子的时候不是原子性操作,这就可能导致多个线程拿到了相同的新种子,产生了相同的随机数,破坏了随机性。random函数使用了一个原子变量能够让新的种子被计算出来之后,其他线程丢弃自己老的种子,而使用新产生出来的种子作为老种子计算自己的新种子,其中通过CAS来控制,保证了随机数的随机性。

二、ThreadLocalRandom

JUC包下的ThreadLocalRandom弥补了Random的缺陷。
它的原理是通过每个线程维护一个种子变量,每个线程计算自己的随机数时,都是根据自己老的种子去计算新的种子,避免了竞争,因此是线程安全的。
同时ThreadLocalRandom继承了Random类,重写了nextInt方法,但是没有继承原子类,而是依赖Thread里面的ThreadLocalRandomSeed变量。

current()方法解析

  • 判断线程是否是第一次调用
  • 如果是则调用初始化方法,初始化中,根据probeGenerator计算当前线程的threadLocalRandomProbe,再根据seeder计算当前线程的初始化种子,再把这个两个变量赋值到当前线程中。
  • 如果不是,则返回当前实例,其中current方法是个静态方法,意味着所有线程返回的都是同一实例。

nextInt方法还是根据当前新种子计算随机数。
nextSeed方法是通过获取当前线程中的threadLocalRandomSeed变量的值,然后累加GAMMA值作为新种子,最后把新的种子放入到当前线程的threadLocalRandomSeed中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值