【问题标题】:Can a Java Random object give different results in different executions for the same seed?Java Random 对象能否在同一种子的不同执行中给出不同的结果?
【发布时间】:2016-09-11 19:18:03
【问题描述】:

假设您有一个 Java 代码,其中您正在使用一个 Random 对象,并使用常量种子进行初始化。在您的代码中,您使用 Random 对象来生成不同的伪随机整数。您没有使用多线程。代码的不同执行是否可能有不同的结果?例如,如果Java编译器为了优化代码而以某种随机方式删除了Random对象的任何冗余调用,那么每次重新编译代码时执行都会有所不同。

【问题讨论】:

  • 程序是否有任何输入会改变其执行顺序?
  • 如果你在不同的 JVM 上运行它可以。我在实践中看到过这种情况。

标签: java random seed


【解决方案1】:

理论上,不同的 JVM 可以对伪随机算法使用不同的实现。不同的 JVM 版本也可以这样做,因为它没有在任何地方指定它需要为不同版本之间的给定种子返回相同的值。然而据我所知,Oracle JDK 中的Random 实现自成立以来一直是相同的。

给定相同的执行环境,保证输出。

【讨论】:

    【解决方案2】:

    鉴于您在同一系统上使用相同的 JVM,我认为它应该是一致的。我刚刚尝试了以下方法。

    import java.util.Random;
    
    public class test
    {
        public static void main(String[] args)
        {
            Random r = new Random(123);
            System.out.println(r.nextInt());
        }
    }
    

    每次我在我的机器上运行它时,它都会给出相同的输出。我在 Ubuntu 16.04 上使用 Open JDK 1.8.0_91。运行此代码时得到的值为 -1188957731。为什么不尝试运行它,看看是否得到相同的值。

    【讨论】:

      【解决方案3】:

      除非您引入任何其他熵源(例如使用输入或环境可能影响程序的某种方式),否则相同的随机种子将在每次执行时产生相同的结果。

      请注意,这依赖于相同字节码的执行。从理论上讲,更改编译器以编译相同的源代码可能会产生不同的字节码,从而产生不同的输出,但很难找到一个真实的例子来证明这一点。

      【讨论】:

        【解决方案4】:

        不,这几乎是guaranteed,假设两次运行之间的环境相同。

        可以使用种子状态从任意初始状态启动 PRNG。使用该状态初始化时,它将始终产生相同的序列

        感谢上帝,优化器将永远不会更改任何会对副作用产生直接影响的内容。

        如果它删除了死代码,那是因为代码在程序的每个可能状态下都被认为是死代码,所以对Random的调用顺序没有可能的影响。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-05
          • 2017-05-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多