gpt4 book ai didi

c# - 此线程使用此 ConcurrentDictionary 和 AddOrUpdate 方法是否安全?

转载 作者:行者123 更新时间:2023-12-01 22:09:54 31 4
gpt4 key购买 nike

我对 C# 中的并发字典有疑问。

在另一个问题中,有人问我如何拥有一个以哈希集作为值的并发字典,但使用哈希集并不是一个好主意,最好使用并发字典作为值。所以我得到的解决方案是这样的:

var myDic = new ConcurrentDictionary<long, ConcurrentDictionary<int, byte>>();
myDic.AddOrUpdate(key,
_ => new ConcurrentDictionary<int, byte>(new[] {new KeyValuePair<int, byte>(element, 0)}),
(_, oldValue) => {
oldValue.TryAdd(element, 0);
return oldValue;
});

假设我有两个线程,其中“元素”在线程 A 中为 1,在线程 B 中为 2。

我怀疑这是否是线程安全的。我可能是错的,但我认为并发字典是这样工作的:

线程A:尝试为key 1插入元素1。key 1不存在,所以它尝试用并发字典ConcurrentDictionary<int, byte>(new[] {new KeyValuePair<int, byte>(1, 0)插入key 1 .

线程B:尝试向键1的字典中插入item 2,线程A还在添加新的键/值,线程B认为键1不存在,所以尝试添加值ConcurrentDictionary<int, byte>(new[] {new KeyValuePair<int, byte>(2, 0)到关键 1。

线程A成功插入键/值对。

线程 B 试图完成,但现在键 1 存在,因为线程 A 插入了键 1。因此线程 B 无法插入键/值。

然后呢?线程 B 的工作被丢弃,所以我在并发字典中只有一项用于键 1?或者线程 B 可能进入 updateValueFactory并将项目 2 添加到字典中?

最佳答案

AddOrUpdate 专为处理您描述的场景而设计;如果它不能优雅地处理它,它就没有用了。

当线程 B 尝试添加其计算值时,它将失败,因为该键已经存在。然后它将自动重试,此时它将执行更新而不是添加。具体来说,它将更新线程 A 产生的值。这是一种乐观并发的形式:算法假定它会成功,因此它会针对该结果进行优化,但它有一个回退计划以防万一失败。

但是请注意,此方法的乐观并发性质意味着您的 addValueFactoryupdateValueFactory 可能两者 都被调用;严格来说,这不是其中之一。在您假设的场景中,线程 B 将首先调用 addValueFactory,并且由于添加失败,稍后调用 updateValueFactory。在竞速更新的情况下,updateValueFactory 可能会在更新最终成功之前调用多次。

关于c# - 此线程使用此 ConcurrentDictionary 和 AddOrUpdate 方法是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48670104/

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