java 提高随机数效率_JAVA高效的随机数生成器

#java##Java##程序员#

a3318c941136e31422f9e0be7c9e8802.gif

JAVA高效的随机数生成器-1.jpg (76.11 KB, 下载次数: 0)

2020-11-14 23:27 上传

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

几年前的写法

a3318c941136e31422f9e0be7c9e8802.gif

JAVA高效的随机数生成器-2.jpg (12.39 KB, 下载次数: 0)

2020-11-14 23:27 上传

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

一、如果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的乘方,那么取模操作符(%)将返回一个负数。这几乎肯定会使程序失败,而且这种失败很难重现!

正常的写法

a3318c941136e31422f9e0be7c9e8802.gif

JAVA高效的随机数生成器-3.jpg (11.55 KB, 下载次数: 0)

2020-11-14 23:27 上传

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

优秀的 ThreadLocalRandom

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

a3318c941136e31422f9e0be7c9e8802.gif

JAVA高效的随机数生成器-4.jpg (14.35 KB, 下载次数: 0)

2020-11-14 23:27 上传

ThreadLocalRandom写法

a3318c941136e31422f9e0be7c9e8802.gif

JAVA高效的随机数生成器-5.jpg (27.58 KB, 下载次数: 0)

2020-11-14 23:27 上传

SplittableRandom写法

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值