gpt4 book ai didi

java - IntStream 来自 Random 和 Random 并发

转载 作者:搜寻专家 更新时间:2023-10-30 21:30:26 24 4
gpt4 key购买 nike

使用相同的 Random 实例来生成一个流(或并行流)并影响其中一部分的流是否安全?

考虑下面的代码。相同的 gen 用于生成并行 IntStream 并每隔几个字符生成一个随机空间。它运行并成功完成,没有抛出异常。

但是这段代码线程安全吗?看起来是这样,因为没有无效(超出范围)的字符值。我想我应该破坏 Random 的内部数据,因为它的方法没有标记为 synchronized,但显然情况并非如此。为什么?

public class RandomGenTest {

Random gen = new Random();

String getRandomText(int len, double spaceProb) {
return gen.ints(len, 'a', 'z'+1)
.map(i-> gen.nextDouble()<spaceProb?' ':i)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();
}

@Test
public void test() {
for (int a=10000; a<10000000; a*=2) {
String text = getRandomText(a, .2);
Assert.assertTrue(text.chars().allMatch(c -> (c>='a' && c<='z') || c==' '));
}
}

}

最佳答案

随机Javadoc拼写出来:

Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.

Random 是一个线程安全的对象,因为 AtomicLong 保留了当前的种子,所以使用它可以逆转大部分并行加速,这是你的重点运动。

改为使用 ThreadLocalRandom.getCurrent() 并至少避免争用问题(尽管引入了 ThreadLocal 查找的开销)。还可以使用 SplittableRandom 检索外部随机数流。此实现允许随机访问流元素,这是良好并行性的关键。

import static java.util.concurrent.ThreadLocalRandom.current;

String getRandomText(int len, double spaceProb) {
return new SplittableRandom().ints(len, 'a', 'z'+1).parallel()
.map(i -> current().nextDouble()<spaceProb ? ' ' : i)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();

关于java - IntStream 来自 Random 和 Random 并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32112472/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com