前言
最近在写一些业务代码时遇到一个需要产生随机数的场景,这时自然想到 jdk 包里的 Random
类。但出于对性能的极致追求,就考虑使用 ThreadLocalRandom
类进行优化,在查看 ThreadLocalRandom 实现的过程中,又追了下 Unsafe
有部分代码,整个流程下来,学到了不少东西,也通过搜索和提问解决了很多疑惑,于是总结成本文。
Random 的性能问题
使用 Random 类时,为了避免重复创建的开销,我们一般将实例化好的 Random 对象设置为我们所使用服务对象的属性或静态属性,这在线程竞争不激烈的情况下没有问题,但在一个高并发的 web 服务内,使用同一个 Random 对象可能会导致线程阻塞。
Random 的随机原理是对一个”随机种子”进行固定的算术和位运算,得到随机结果,再使用这个结果作为下一次随机的种子。在解决线程安全问题时,Random 使用 CAS 更新下一次随机的种子,可以想到,如果多个线程同时使用这个对象,就肯定会有一些线程执行 CAS 连续失败,进而导致线程阻塞。
ThreadLocalRandom
jdk 的开发者自然考虑到了这个问题,在 concurrent 包内添加了 ThreadLocalRandom
类,第一次看到这个类名,我以为它是通过 ThreadLocal 实现的,进而想到恐怖的内存泄漏问题,但点进源码却没有 ThreadLocal 的影子,而是存在着大量 Unsafe 相关的代码。(