Random与ThreadLocalRandom 源码小析

1、Random

image.png

随机数生成主要有两个步骤

(1)首先获取当前种子作为老种子
(2)然后根据老种子计算新种子
(3)最后根据新种子计算出新的随机数

种子seed是原子变量,通过CAS操作保证只有一条线程可以更新老的种子为新的。失败的线程会通过循坏重新获取更新后的种子去计算新种子,这样就保证了随机数的随机性

高并发下的性能问题

当计算新种子时,多个线程会竞争同一个原子变量的更新操作,由于原子变量的更新是CAS操作,同一时刻只会有一个线程会成功,所以会造成大量线程进行自旋重试,从而降低并发性能。

2、ThreadLocalRandom

生成随机数步骤与Random类似。 区别是ThreadLocalRandom使用ThreadLocal原理,让每个线程都都持有一个本地的种子变量,这样在计算随机数时就不会存在竞争问题了。

image.png
image.png

可以看到,计算随机数时,实际上是先获取当前线程的threadLocalRandomSeed变量作为当前种子来计算新种子,然后再把新种子更新回threadLocalRandomSeed变量中。
这里的threadLocalRandomSeed只是Thread类里面的一个普通long变量,因为这个变量是线程级别的,所以根本不需要使用原子性变量了。