JRE或平台之间的java.util.Random实现是否不同?

时间:2012-03-28 12:16:39

标签: java random

当我在Eclipse中查看源代码时,next的{​​{1}}方法基本上是:

java.util.Random

如何确定不同的JDK或JVM是以不同的方式或使用不同的常量实现seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); return (int)(seed >>> (48 - bits));

我已经在Weird behaviour when seeding Java Random中遇到了不同的无参数构造函数。我想知道next方法是否会发生类似的事情。我在哪里可以找到不同实现的来源?

2 个答案:

答案 0 :(得分:5)

Random.next()的Javadoc明确说明了使用哪种算法生成下一个数字。

理论上可能不同的JVM可能使用不同的算法,但这不太可能,特别是如果您将自己限制为基于Sun / Oracle库的JVM。


  

该文档是否必然适用于所有JDK?

你需要检查以确定,但可能是的。这是Sun / Oracle不太可能改变的事情,因为有可能破坏过去15年左右的大量现有Java应用程序和测试套件。

以下是一些事实:

  • Java 1.3.1到Java 1.7(*)的javadoc包含与此方法完全相同的规范,

  • 如果符合规范,则只允许使用商标“Java”

  • 大多数(如果不是全部)Java(TM)实现使用派生自Oracle / Sun源代码的类库,

  • 开发人员会注意到使用了不同的算法......并大声抱怨。

因此,使用不同算法实现Java(TM)的可能性非常小。

(*我在网上找不到Java 1.1 javadocs,但我期待他们会说同样的话。)

答案 1 :(得分:4)

  

如何确定不同的JDK或JVM是否会以不同的方式或使用不同的常量实现?

通过在不同JVM上的程序中使用相同的种子,并查看是否获得相同的序列,因为序列对于给定的种子是确定性的。

我不确定JDK是否可以使用不同的算法,因为documentation for next说:

  

方法next由类Random通过原子方式更新种子来实现

     

(seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)

     

并返回

     

(int)(seed >>> (48 - bits)).

     

这是一个线性同余伪随机数发生器,由DH Lehmer定义并由Donald E. Knuth在计算机编程艺术,第3卷: Seminumerical Algorithms 中描述,第3.2.1节。

......这似乎设定了一个特定的合同,虽然就在它之前它说

  

next的一般合同是它返回int值,如果参数bits介于132之间(包括),那么返回值的许多低位将是(近似)独立选择的位值,每个位值(大致)可能是01

...也许这样就可以让算法摆脱困境。

  

我在哪里可以找到不同实现的来源?

如果它们是开源的,大概你可以在项目的回购中找到实现。如果他们关闭了,那么......