gpt4 book ai didi

scala - parallelsim下scala并发类和非并发类的区别

转载 作者:行者123 更新时间:2023-12-01 13:31:45 24 4
gpt4 key购买 nike

在 Scala - coursera 上的函数式编程类(class)中,以下代码段被描述为在并发情况下失败。如果将 mutable.Set 替换为并发类,该代码段将会成功。

def intersection(a: GenSet[Int], b: GenSet[Int]): Set[Int] = {
val result = mutable.Set[Int]()
for (x <- a) if (b contains x) result += x
result
}
intersection((0 until 1000).toSet, (0 until 1000 by 4).toSet)
intersection((0 until 1000).par.toSet, (0 until 1000 by 4).par.toSet)

Rule: Avoid mutations to the same memory locations without proper synchronization.

并发类和非并发类有什么区别,或者非并发类在并行下会失败的原因是什么?

最佳答案

在没有同步的情况下同时向Set追加元素时,Set无法正确处理冲突或者位置计算错误。因此对于您的示例,res2 可能会有重复字段 或更少一些字段。

解释:

对于:

for (x <- a) if (b contains x) result += x
result
}

result += x 存在竞争条件。它等于result.addEntry(x) , 但对于这种方法,它不是线程安全的

var h = index(newEntry.hashCode)
var curEntry = table(h)
while (null != curEntry) {
if (curEntry == newEntry) return false
h = (h + 1) % table.length
curEntry = table(h)
//Statistics.collisions += 1
}
table(h) = newEntry

在上面的代码中,当试图同时向HashTable追加元素时。可能是计算错误的位置或遇到错误的碰撞。例如,当尝试将newEntry添加到Set中时,实际上它不存在于set中,它会直接转到表(h) = newEntry,但同时,有一个新值,它与newEntry具有相同的hashcode,但对于第一个newEntry 仍未完成 table(h) = newEntry,因此 newEntry 将被 second 值覆盖。

所以对于同步,也许你可以这样做:

for (x <- a) {
if (b contains x) {
this.synchronized {
result += x
}
}
}

关于scala - parallelsim下scala并发类和非并发类的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45687593/

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