java random产生随机数_JAVA高效的随机数生成器

#java# #Java# #程序员#

76c635d83aa5fb1c48f7c42fd00189b9.png

不知好几年前的一个问题:假设你希望产生位于0和某个上界之间的随机整数,你该怎么去做?时隔多年后又重新记起,转眼一看,她已经有了很大的发展。

几年前的写法

0271c31aa1a8907324d8b8dbfddeda53.png

突然翻出几年前写的东西,看到这个原始的写法,顿感漏洞百出。虽然这个写法目前都还感觉不错,但是有着三大缺陷。

一、如果n是一个比较小的2的乘方,经过一段相当短的周期之后,它产生的随机数序列将会重复,生成的效率低下。

二、如果n不是2的乘方,那么平均起来,有些数会比其他的数出现得更为频繁。

如果n比较大,这个缺点就会非常明显,如果将N我们暂定为100万,重复执行1万次,我们会发现它打印出来的数接近于666666。由random方法产生的数字有三分之二落在随机数取值范围的前半部分。随机值就变成不是随机值了。

调侃一句:说不定TX的抽奖就是这样的,我多年抽奖不中的原因貌似找到了。

三、在极少数情况下,它会失败,因为会返回一个落在指定范围之外的数。

因为这个方法试图通过调用Math.abs,将rnd. nextInt()返回的值映射为一个非负整数。如果nextInt()返回Integer.MIN VALUE,那么Math.abs也会返回Integer.MIN_VALUE,假设n不是2的乘方,那么取模操作符(%)将返回一个负数。这几乎肯定会使程序失败,而且这种失败很难重现!

正常的写法

5dffa1947770d8282782dbc8fc56f77b.png

这种写法简单,并且完美地避免了最原始的上面的问题,但是这似乎还不够。

优秀的 ThreadLocalRandom

从Java7开始,提供了一个全新的ThreadLocalRandom,就不应该再使用Random了。现在选择随机数生成器时,大多使用 ThreadLocalRandom。它会产生更高质量的随机数,并且速度非常快。我自己测试了一下,比Random快了3.6倍。但是对于ForkJoin Pool和并行Stream,则推荐使用SplittableRandom。

2f5e834296d6a08db2aa6cab79938344.png

ThreadLocalRandom写法

ee8a8233175c2eee1da184de41e0f83c.png

SplittableRandom写法

不知道友友们,有没有好的建议和意见,觉得不错,点赞支持下,相互交流交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值