Scala中的随机生成器是线程安全的吗
Is the random generator in Scala thread-safe
我有以下代码:
import scala.util.Random
val seq = Seq[Int](1, 2, 3)
val rand = new Random(123)
val gen = seq.par.map(_ => rand.nextInt(3))
println(gen.seq)
它打印出 Vector(2, 2, 2)
。
Scala 中的随机生成器似乎不是线程安全的?
是这样吗?如果是这样,除了为不同的线程使用不同的种子之外,我如何解决它。
此外,如果我在 Scala 中使用 Java 中的随机 class,它仍然是线程安全的吗?
相关问题
- Is Random class thread safe?
说明
par
指的是scala.collection.parallel.immutable
中的par
。但我的电脑似乎不需要我这样做。它在我的电脑上运行。
是的。与 Java 中的相同。我们来看看next
, which is the random generator behind nextInt
:
的实现
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
基本上我们根据seed
计算下一个元素。如果 seed
已经更改,它将创建一个新的 nextseed
,直到成功更新种子。因此它是线程安全的。
出于同样的原因,在您的场景中似乎并非如此。但是,如果我们 运行 相同而没有任何并行性,我们将得到相同的结果。
import scala.util.{Failure, Random, Success}
val seq = Seq[Int](1, 2, 3)
val rand = new Random(123)
val gen = seq.map(_ => rand.nextInt(3))
println(gen.seq)
结果为:
List(2, 2, 2)
代码 运行 在 Scastie。这是因为种子 123
的前三个“随机”数字是 2, 2, 2
我有以下代码:
import scala.util.Random
val seq = Seq[Int](1, 2, 3)
val rand = new Random(123)
val gen = seq.par.map(_ => rand.nextInt(3))
println(gen.seq)
它打印出 Vector(2, 2, 2)
。
Scala 中的随机生成器似乎不是线程安全的?
是这样吗?如果是这样,除了为不同的线程使用不同的种子之外,我如何解决它。
此外,如果我在 Scala 中使用 Java 中的随机 class,它仍然是线程安全的吗?
相关问题
- Is Random class thread safe?
说明
par
指的是scala.collection.parallel.immutable
中的par
。但我的电脑似乎不需要我这样做。它在我的电脑上运行。
是的。与 Java 中的相同。我们来看看next
, which is the random generator behind nextInt
:
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
基本上我们根据seed
计算下一个元素。如果 seed
已经更改,它将创建一个新的 nextseed
,直到成功更新种子。因此它是线程安全的。
出于同样的原因,在您的场景中似乎并非如此。但是,如果我们 运行 相同而没有任何并行性,我们将得到相同的结果。
import scala.util.{Failure, Random, Success}
val seq = Seq[Int](1, 2, 3)
val rand = new Random(123)
val gen = seq.map(_ => rand.nextInt(3))
println(gen.seq)
结果为:
List(2, 2, 2)
代码 运行 在 Scastie。这是因为种子 123
的前三个“随机”数字是 2, 2, 2