I need to do 1000
calculations, each one based on a random number.
The entire run needs to be reproducible.
In a single threaded environment, I just create random based on a seed and use that for each calculation:
Random random = new Random(37);
for (Calculation c : calculations) {
c.doCalculation(r.nextInt());
}
In a multi threaded enviromnent, where I have 10
threads, I 'd have a seeded random seed the thread 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
...
Is this a good idea? Is it still an evenly distributed random in general? The fact that each threadRandom
is seeded by the initRandom
, does it not break the uniform distribution?
For reproducible reasons, I cannot share 1 global random, as some threads might run faster than others in some runs, so they would not always call the global random in the same order (and the contention could cause performance degradation).
You will get an even distribution of numbers via Random, however the order that the each list of Calculation objects in your list will run is not guaranteed so if these then pass the result to a shared list the order may vary over runs.