7.3.5 Java7的ThreadLocalRandom与Randon
Random
类专门用于生成一个伪随机数,它有两个构造器:
- 一个构造器使用默认的种子(以当前时间作为种子),
- 另一个构造器需要程序员显式传入一个
long
型整数的种子
ThreadLocalRandom
类是Java7
新增的一个类,它是Random
的增强版。在并发访问的环境下,使用ThreadLocalRandom
来代替Random
可以减少多线程资源竞争,最终保证系统具有更好的线程安全性。ThreadLocalRandom
类的用法与Random
类的用法基本相似,它提供了一个静态
的current()
方法来获取ThreadLocalRandom
对象,获取该对象之后即可调用各种nextXxx()
方法来获取伪随机数了。
ThreadLocalRandom
与Random
都比Math
的random
方法提供了更多的方式来生成各种伪随机数:
- 可以生成浮点类型的伪随机数,
- 也可以生成整数类型的伪随机数,
- 还可以指定生成随机数的范围。
Random类实例
关于Random
类的用法如下程序所示。
1 | import java.util.*; |
运行效果1:
1 | rand.nextBoolean():true |
运行效果2:
1 | rand.nextBoolean():true |
Random类如何获取大于等于N小于等于M之间的随机数
Random
类nextInt
方法只能传入一个参数,只能获取大于等于0小于N之间的随机整数.如果要获取大于等于N,小于M的随机整数需要通过数学计算来完成.
1 | import java.util.Random; |
1 | 0,1,0,0,0,0,1,0,0,0,1,1,1,1,0,1,0,1,1,0, |
Random对象的种子相同则生成的随机数也相同
Random
使用一个48位的种子,如果这个类的两个实例是用同一个种子创建的,对它们以同样的顺序调用方法,则它们会产生相同的数字序列。
1 |
|
运行上面程序,看到如下结果:
1 | 第一个种子为50的Random对象 |
种子相同随机数相同
只要两个Randon
对象的种子相同,而且方法的调用顺序也相同,它们就会产生相同的数字序列。
也就是说, Random
产生的数字并不是真正随机的,而是一种伪随机。
为了避免两个Random
对象产生相同的数字序列,通常推荐使用当前时间作为Random
对象的种子。
如下代码所示:Random rand=new Random(System.currentTimeMillis());
或者直接Random rand=new Random()
,因为系统会默认使用当前时间作为种子.
ThreadLocalRandom
在多线程环境下使用ThreadLocalRandom
的方式与使用Random
基本类似
如下程序片段示范了ThreadLocalRandom
的用法。
1 | ThreadLocalRandom rand=ThreadLocalRandom.current(); |
ThreadLocalRandom的nextInt
ThreadLocalRandom
的nextInt
方法比Random
提供的nextInt
要强,ThreadLocalRandom
来提供了nextInt(int min, int max)
方法来获取大于等于min
,小于max
的方法.通过ThreadLocalRandom
的这个方法我们可以很方便的获取大于等于N小于等于M之间的随机正整数.