【发布时间】:2017-01-08 07:10:56
【问题描述】:
我需要进行1000 计算,每个计算都基于一个随机数。
整个运行需要可重现。
在单线程环境中,我只是根据种子创建随机数并将其用于每次计算:
Random random = new Random(37);
for (Calculation c : calculations) {
c.doCalculation(r.nextInt());
}
在多线程环境中,我有10 线程,我将有一个种子随机种子线程 Random's:
Random initRandom = new Random(37);
for (List<Calculation> p : calculationPartitions) {
final Random threadRandom = new Random(initRandom.nextLong());
executorService.submit(() -> {
for (Calculation c : p) {
c.doCalculation(threadRandom.nextInt());
}
});
}
// Merge the calculation results back in the same order as the calculationPartitions
...
这是个好主意吗? 总的来说,它仍然是一个均匀分布的随机数吗?每个threadRandom 都被initRandom 播种,不破坏均匀分布吗?
出于可重现的原因,我不能共享 1 个全局随机数,因为某些线程在某些运行中可能比其他线程运行得更快,因此它们不会总是以相同的顺序调用全局随机数(争用可能会导致性能下降)。
【问题讨论】:
-
Random生成均匀分布的数字,所以答案是:是的。 -
这是一个合理的想法。如果您共享一个随机数,它们是同步的,这使得在不同线程中使用相同的随机数变得困难。您甚至可以使用除
List<Calculation>之外的其他东西,而是使用包含List并且还包含Random的自定义类。 -
@Andreas 所以线程都使用由原始 Random 中的随机数播种的 Random 的事实不会破坏均匀分布的保证?
-
Random 是用特定值(硬编码或来自其他地方)播种的事实,并不会改变 Random 从那时起生成均匀分布的数字的事实。如果种子 Random 没有做到这一点,那么对于单线程环境,您甚至无法做到这一点,现在可以吗?
-
Geoffrey,请看stackoverflow.com/questions/28991299/… 和内部讨论,它可能会给你一些见解...
标签: java random distribution uniform-distribution