因此,我的ConcurrentDictionary中有一个ConcurrentDictionary值。
ConcurrentDictionary<int, IList<string>> list1 = new ConcurrentDictionary<int, IList<string>>;为了更新列表中的值,我执行以下操作:
if (list1.ContainsKey[key])
{
IList<string> templist;
list1.TryGetValue(key, out templist);
templist.Add("helloworld");
}但是,向templist添加字符串会更新ConcurrentDictionary吗?如果是的话,更新线程是否安全,这样就不会发生数据损坏?
或者是否有更好的方法来更新或创建ConcurrentDictionary中的列表
编辑
如果我使用的是ConcurrentBag而不是列表,我将如何实现这一点?更具体地说,我如何更新它?ConcurrentDictionary的TryUpdate方法感觉有点过火了。
ConcurrentBag.Add是否在线程安全的mannar中更新ConcurrentDictionary?
ConcurrentDictionary<int, ConcurrentBag<string>> list1 = new ConcurrentDictionary<int, ConcurrentBag<string>>发布于 2017-01-11 13:31:42
首先,不需要做ContainsKey()和TryGetValue()。
你应该这么做:
IList<string> templist;
if (list1.TryGetValue(key, out templist))
templist.Add("helloworld");实际上,编写的代码有一个争用条件。
在调用ContainsKey()和TryGetValue()的一个线程之间,可能有不同的线程使用该键删除了项。然后TryGetValue()将返回tempList为null,然后在调用tempList.Add()时将得到一个空引用异常。
其次,是的:这里还有另一个可能的线程问题。您不知道字典中存储的IList<string>是线程安全。
因此,不能保证调用tempList.Add()是安全的。
您可以使用ConcurrentQueue<string>而不是IList<string>。这可能是最可靠的解决方案。
注意,仅仅锁定对IList<string>的访问是不够的。
这是不好的:
if (list1.TryGetValue(key, out templist))
{
lock (locker)
{
templist.Add("helloworld");
}
}除非您在任何地方都使用相同的锁,否则可以访问IList。这并不容易实现,因此最好要么使用ConcurrentQueue<>,要么向该类添加锁定,然后更改体系结构,这样就不会有其他线程访问底层IList。
发布于 2017-01-11 13:29:32
可以说,线程安全字典上的操作按键是线程安全的.因此,只要您只从一个线程访问您的值(在本例中是一个IList<T>),您就可以继续了。
ConcurrentDictionary执行而不是,同时阻止两个线程访问一个键下面的值。
发布于 2017-01-11 13:32:21
https://stackoverflow.com/questions/41592129
复制相似问题