多线程并发主题 -ThreadLocalRandom 类
Random类简介
Random类的不足之处
ThreadLocalRandom简介
ThreadLocalRandom原理剖析
Random与ThreadLocalRandom实际执行情况对比
ThreadLocalRandom类总结
Instances of {@code java.util.Random} are threadsafe. However, the concurrent use of the same {@code java.util.Random} instance across threads may encounter contention and consequent poor performance. Consider instead using {@linkjava.util.concurrent.ThreadLocalRandom} in multithreaded designs.
摘自Random类注释:
java.util.Random实例是线程安全的,然而,如果是在高并发的场景下使用,则其性能会降低。可以在多线程的场景下,使用java.util.concurrent.ThreadLocalRandom来替代java.util.Random。
环境:
JDK 1.7
Random类简介
Random类是jdk util包中的一个随机数生成类。其基本使用如下:
通过以上代码就可以生成0至5之间的随机整数(包含0,不包含5)。
Random生成随机数的过程如下:
1.首先实例化Random类,这时会初始化一个long型的种子值。
2.这个seed种子值可以以两种方式初始化,一种时根据系统时间,也就是通过无参方式初始化。
3.另外一种方式是根据固定种子值初始化,也就是有参方式。
4.seed种子的作用就是为了生成随机数(这里我们主要探究Random类与ThreadLocalRandom类的比较,所以对seed的生成过程源码不做探究,只说明作用),如果种子值相同,那么生成的随机数也是“相同”的。如下:
5.有了种子后,就可以通过java.util.Random#nextInt()方法生成随机数了。在多线程环境下,多条线程会拿到相同的种子吗?答案是不会,在Random类中有一个方法,避免多线程环境下,线程共用一个种子值,java.util.Random#next(int bits)
能看到,方法中使用原子类AtomicLong,并用自旋操作保证一个至多会有一个线程更新种子值,这就可以保证Random是线程安全的。
Random类的不足之处
以上就是Random类生成随机数的过程,我们看到Random类来保证线程安全的关键是通过原子类的自旋操作保证的,cas是乐观锁的实现,适用于多线程少量更新的情况,一旦有大量更新的场景,自旋操作就会大量耗费cpu的资源,带来性能的下降,那么有没有方法解决Random在多线程环境下的性能问题呢,ThreadLocalRandom为我们提供了解决方案。
ThreadLocalRandom简介
JUC下的ThreadLocalRandom类是线程安全的类,它的作用和random一样,生成随机数。
根据类名,我们很容易想到ThreadLocal类,而ThreadLocalRandom保证线程安全的机制也是运行ThreadLocal的方式实现的,使用ThreadLocalRandom生成随机数的代码如下:
ThreadLocalRandom实例化是通过静态方法:ThreadLocalRandom.current(),
在多线程环境下,为什么ThreadLocalRandom的性能就明显优于Random类呢?不同于Random类,ThreadLocalRandom的种子是保存在本地线程中的,不存在种子值的资源共享问题,ThreadLocalRandom类创建本地线程的是类中的current方法,ThreadLocalRandom.current()方法的代码如下:
显而易见,每一个线程去调用ThreadLocalRandom.current()都会生成一个本地线程的实例ThreadLocal<ThreadLocalRandom> localRandom;这里本地线程的变量就是ThreadLocalRandom;
ThreadLocalRandom原理剖析
ThreadLocalRandom源码分析
实例化ThreadLocalRandom
2.
Random与ThreadLocalRandom实际执行情况对比
ThreadLocalRandom类总结
版权声明: 本文为 InfoQ 作者【Geek_896619】的原创文章。
原文链接:【http://xie.infoq.cn/article/e0e1c0b0e838693169851f50f】。文章转载请联系作者。
评论