ConcurrentDictionary.GetOrAdd 嵌套集合

问题描述 投票:0回答:1

我已经读过这个问题,但我仍然不明白如果我有一个嵌套集合,GetOrAdd 是如何工作的。

ConcurrentDictionary.GetOrAdd 真的是线程安全的吗?

如果我还没有创建嵌套集合,并且从多个线程同时调用 GetOrAdd,会发生什么? 我期望这样的行为:只有一个线程能够创建一个新集合,其余线程将接收已创建的集合并在那里添加一个值。事情会是这样吗?

   var completions = subscribers.GetOrAdd(key, _ => new ConcurrentBag<TaskCompletionSource<string>>());
    completions.Add(completion);
c# concurrency
1个回答
0
投票

我期望只有一个线程能够创建一个新集合的行为,

不完全是。完全有可能有多个线程创建一个新的

TValue
,但只有这些
TValue
之一会添加到字典中。其他
TValue
将超出范围并被丢弃(垃圾收集)。

其余的将收到已经创建的并在那里添加一个值。

是的,所有线程都会与同一个

TValue
进行交互。
GetOrAdd
返回由赢得乐观锁定竞赛的线程创建的
TValue
。竞争是乐观的,因为
valueFactory
委托是在
ConcurrentDictionary<TKey,TValue>
集合内部使用的锁之外调用的。该集合不允许悲观锁定,即您不能使用其内部锁来保护您自己的代码。悲观锁定在某些情况下可能是有益的,但此集合根本不支持此功能。

© www.soinside.com 2019 - 2024. All rights reserved.