繁体   English   中英

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

[英]Java Configuring random number generators in multi-threaded environment

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

  1. 鉴于我想播种RNG以获得可重复性,因此将变量声明为static有意义吗?
  2. 我可能需要添加更多需要随机数的不同类。 我是否应该将RNG移到一个单独的类,以便仍可以在整个应用程序中使用一个种子? 如果是这样,我应该使用static Random还是singleton对象?
  3. 如果我决定在多个线程中使用随机数会怎样? 似乎如果我使用类似2.的策略,我可能仍然会失去可预测性,因为我无法确定地说线程将访问RNG的顺序。 RNG仍将生成相同的,可预测的随机数序列,但是从程序的一次运行到另一轮,抓取序列中第一个(或第n个)随机数的线程可能会有所不同。
  4. 这对我来说表明,每个线程都需要自己的RNG,以便在所有运行中都可重现结果。 这是否意味着每个线程都需要自己的种子? 如果是这样,那将保证可重复性,还是我需要做其他事情来消除由多个线程导致的随机性?
  5. 有没有一种方法可以从单个数字生成种子,从而最大程度地减少不同RNG之间的相关性?

换句话说,如果线程0具有Random thread0RNG = new Random(seed)且线程1具有Random thread1RNG = new Random(seed) ,则我只需要一个种子,但是每个线程中的随机数将高度相关。 我可以有两个种子,但是然后我无法将程序的运行与在命令行上传递的单个数字相关联。 是否可以说出seed0 = someFunction(seed,0)seed1 = someFunction(seed,1)吗?

是的,您应该为每个线程分配自己的Random对象,以避免由于线程计时而产生不可重复的交织。

您都可以使用相同的编号为它们播种,但随后它们都将获得完全相同的编号序列。 我不知道这是不是一个问题。

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

首先, Random是线程安全的,因此您可以在多个线程中安全地使用它,尽管由于锁定,只有一个Random实例可能会导致性能下降。 为避免这种情况,请改用ThreadLocalRandom

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

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

因此,我建议使用中央RNG为所有其他RNG生成种子 但是请注意,这仅是可预见的,前提是RNG的播种顺序已明确定义-同样,在并发环境中,这可能不是直截了当的,而是可行的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM