[英]Java Configuring random number generators in multi-threaded environment
我有一个使用伪随机数的应用程序。 在测试应用程序时,我需要可重复性,我通过为随机数生成器使用种子来安排可重复性。 当前,RNG在使用它作为静态变量的类中声明: private static Random rng = new Random(seed)
。 我有几个问题。
static
有意义吗? static Random
还是singleton对象? 换句话说,如果线程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.