Java在多线程环境中配置随机数生成器

Java在多线程环境中配置随机数生成器,java,multithreading,random,Java,Multithreading,Random,我有一个使用伪随机数的应用程序。当我测试应用程序时,我需要再现性,我通过使用随机数生成器的种子来安排。目前,RNG在将其用作静态变量的类中声明:private static Random RNG=new Random(seed)。我有几个问题 鉴于我想为RNG的再现性设定种子,声明变量static有意义吗 我可能需要添加更多需要随机数的不同类。我是否应该将RNG移动到一个单独的类,这样我仍然可以为整个应用程序使用一个种子?如果是这样,我应该使用静态随机还是单例对象 如果我决定在多个线程中使用随机

我有一个使用伪随机数的应用程序。当我测试应用程序时,我需要再现性,我通过使用随机数生成器的种子来安排。目前,RNG在将其用作静态变量的类中声明:
private static Random RNG=new Random(seed)
。我有几个问题

  • 鉴于我想为RNG的再现性设定种子,声明变量
    static
    有意义吗
  • 我可能需要添加更多需要随机数的不同类。我是否应该将RNG移动到一个单独的类,这样我仍然可以为整个应用程序使用一个种子?如果是这样,我应该使用
    静态随机
    还是单例对象
  • 如果我决定在多个线程中使用随机数,会发生什么?如果我使用像2这样的策略,我可能仍然会失去可预测性,因为我无法确定线程访问RNG的顺序。RNG仍将生成相同的、可预测的随机数序列,但从程序的一次运行到另一次运行,获取序列中第一个(或第n个)随机数的线程可能不同
  • 这向我表明的是,每个线程都需要自己的RNG,以便在所有运行中都能再现结果。这是否意味着每个线程都需要自己的种子?如果是这样的话,这能保证再现性吗,或者我还需要做些什么来消除多线程可能带来的随机性
  • 是否有一种方法可以从单个数字生成种子,从而最小化不同RNG之间的相关性

  • 换句话说,如果线程0有
    Random-thread0RNG=new-Random(seed)
    ,线程1有
    Random-thread1RNG=new-Random(seed)
    ,我只需要一个种子,但每个线程中的随机数高度相关。我可以有两个种子,但是我不能将程序运行与通过命令行传递的单个数字相关联。是否可以适当地说
    seed0=someFunction(seed,0)
    seed1=someFunction(seed,1)

    是的,您应该为每个线程提供自己的随机对象,以避免由于线程计时而导致无法生成的交错

    你可以用相同的数字给它们播种,但是它们都会得到完全相同的数字序列。我不知道这是否是个问题


    如果出现问题,可以使用一个“主”随机对象为其他对象生成种子。每次创建新线程时,从主线程获取种子。但是您必须确保每次都以相同的顺序创建所有线程(或者至少检索种子)

    为每个线程使用RNG,例如。如果每个线程都有自己的生成器,那么多线程不会影响随机性。种子的选择取决于您。

    首先,
    Random
    是线程安全的,因此您可以跨多个线程安全地使用它,尽管由于锁定,使用单个
    Random
    实例可能会导致性能差。要避免这种情况,请改用
    ThreadLocalRandom

    但如果您的案例中需要可预测性,那么这并不是解决方案。在并发环境中只有一个共享RNG是不可预测的。因此,您是对的,每个线程需要一个实例,并且每个实例都必须用一个种子进行初始化

    但是,如果所有RNG实例使用相同的种子,那么生成的随机序列不仅高度相关,而且完全相同!因此,您必须为所有RNG使用不同的种子


    因此,我建议使用一个中央RNG为所有其他RNG生成种子。但是请注意,这是可以预测的,如果RNG的播种顺序定义得很好——同样,在并发环境中,这可能不是直接的,而是可行的。

    根据SO规则,一个问题应该有一个特定的问题。是吗?关于
    单例设计模式如何
    ?我认为给出一个你希望你的程序做什么的例子会很有用,这样你就能得到真正对你有帮助的答案。你不能在ThreadLocalRandom中植入种子。所以这是不可复制的。我担心,如果我用同一个随机数生成器生成它们的种子,那么这些随机数生成器的相关性会太密切。而不是相同的序列,序列只会移动几个地方,不是吗?我想我应该测试一下…Correlated:是的。但不是以琐碎的方式。简单地移动几个位置:取决于使用的算法。你可以增加一个固定数量的种子。那会把事情搞混的。我刚刚玩了10个随机的实例,它们是由一个主实例播种的。我已经创建了100个随机双精度序列。所有可能的序列对中没有一对的相关系数高于0.2。大多数都低于0.05。仅使用0到9的整数作为种子也会产生相关系数较低的随机序列。也许这里需要更复杂的统计测试。谢谢大家的帮助。我决定采用以下方法:使用随机数的每个线程都有一个键。主种子将提供给程序。线程将使用其密钥和加密哈希函数对种子进行哈希,以获取其线程本地随机数生成器的种子。这降低了RNG之间的相关性,并消除了种子依赖于线程运行顺序的可能性。