Random 类的一个有趣现象

前言

前两天在写“随机报数机”的时候,用到了 Random 类,来生成随机数,发现一个现象:有时候 Random 类出来的数字连着好几次都是一样的,我就在想,这个数字到底是不是“随机”生成的,于是做了一个小实验。

实验

代码思路:新建一个线程,线程无线循环,每循环一次,由 Random 类生成一个随机数,根据随机数的值,让与数值对应的 panel 控件向上移动一个单位,就形成了类似于柱状图实时统计的效果。

这个时候,Random random = new Random();  这句代码,放在不同的位置,就有两种不同的效果。为了让程序跑的快一些,我都尽量避免对界面的没有必要的访问。

第一种Random random = new Random();  放在循环外

random2

最终的效果如下图所示,Random 类基本照顾到了范围内的所有数,整体基本平稳增加。

random6


第二种Random random = new Random();  放在循环内

random1

效果如下图所示,柱状图的上升非常突兀,整体不如第一种情况增长的平缓,差异很明显。

柱状图的突增说明 Random 类确实在一段时间内持续“宠幸”了某一个数,从画面看来就是某个柱状条的激增。

random5

进一步实验

如果给循环加一个延时:

对于第一种情况:现象没有什么变化,也是平稳增加,只不过增加的慢了一点,这里就省略了。

对于第二种情况:表现发生了相当大的变化,代码如下所示:

random3

interval 等于 1,就是加了 1 ms 的延时,速度慢了点,但是 Random 不再连续随机到某一个数,整体上升平稳。

random6

后记

现象 1 :实例化对象的代码的位置不同,效果不同。

猜想 1 :可能是放在循环内部的时候,每次都是新实例化的对象,这样每个数被随机到的概率都是相同的(假设 Random 类真的完全模拟了自然随机事件)。放在循环外部,第二次的循环可能会有意避开第一次的循环。

现象 2 :实例化放在循环内部的时候,加了 1 ms 的延迟,Random 不再持续“宠幸”某一个数,打破了猜想 1。

猜想 2 :Random 类可能与时间有关。

猜想 3 :在控制台中,将实例化放在循环内,Random 类持续“宠幸”某个数的行为将更加严重,因为前后间隔时间更短。

若要查明真相,估计要查阅 Random 类的 源码,我点进去看了下,emmmmmm,以后再研究吧,还有别的事情要做[跑路]。

2 thoughts on “Random 类的一个有趣现象

  1. C语言里随机函数要调用当前时间,出来的随机数差距都不是很大。

    • Bluesummer

      后来知道时间方法有一个叫“种子”的东西,谢谢!

发表评论