如果字典不包含给定键的值,它是否只返回false,或者由于线程竞争条件它也会返回false,就像另一个线程添加/更新某些东西一样?
代码中的问题:
ConcurrentDictionary<int, string> cd = new ConcurrentDictionary<int, string>();
// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one");
// Will this ever fail if no other thread ever removes with the key value of 1?
cd.TryRemove(1);
修改 我认为如果它不包含给定键的值,它只返回false,但是想要绝对确定。
答案 0 :(得分:72)
虽然Mitch is right ConcurrentDictionary
不容易受到竞争条件的影响,但我认为您要问的答案是肯定的,如果密钥存在,TryRemove
将有效并将返回true
。
在您发布的代码中,TryRemove
无法返回false
,因为cd
是一个其他地方无法访问的本地变量。但是如果其他地方的某些代码被赋予对这个ConcurrentDictionary
对象的引用并且正在删除单独线程上的键,那么TryRemove
可能会返回false
,即使在这里 - 但是只是因为密钥已被删除,不是因为字典上正在执行某些其他操作而且密钥以某种方式“卡在”那里。
答案 1 :(得分:6)
ConcurrentDictionary没有受到竞争条件的影响。这就是你使用它的原因。
返回值
如果删除了某个对象,则为true 成功;否则,错误。
答案 2 :(得分:1)
要做的另一点:
// This might fail if another thread is adding with key value of 1. cd.TryAdd(1, "one");
此评论不正确,可能会对“尝试”的含义产生同样的误解。它不是要同时添加的尝试,而是是否已使用键1
添加了值。
考虑标准Dictionary<TKey,TValue>
。等效代码为:
if (!d.Contains(1))
d.Add(1, "one");
这需要两个操作。没有办法将这样的API设计为线程安全的,因为cd
可能在调用1
和Contains
之间添加了键Add
的值,这会导致在Add
投掷。
并发集合具有API,这些API在单个API后面逻辑地将这些测试 - 操作对捆绑到单个原子操作中。