例如我有var linkedList = new LinkedList<int>();
然后我添加一个节点。 linkedList.AddLast(1);
之后我有两个线程分别调用linkedList.AddLast(2);
(同一语句)。
我可以安全地预期它会变成1-> 2&gt; 2链表吗?
或者当竞争条件发生时它可以变成1-> 2?
(也许它也有可见性问题,但在此之前我首先想知道这种竞争条件是否会发生。)
答案 0 :(得分:4)
这个问题可以通过快速的小测试应用轻松解决。答案是有时会发生1&gt; 2。
private static void RunTest()
{
for (int i = 0; i < 100; i++)
{
var lst = new LinkedList<int>();
Parallel.For(1, 51, j =>
{
lst.AddLast(j);
});
if (lst.Count < 50)
{
Console.WriteLine(lst.Count);
}
}
}
如前所述,此集合不是线程安全的。您需要序列化访问权限或使用内置的线程安全集合。
答案 1 :(得分:1)
不,你不能。我可以安全地预期它会变成1-> 2&gt; 2链表吗?
LinkedList<T>
不是线程安全的。
来自MSDN:
Stephan Toub在他的一个答案中说:此类型不是线程安全的。如果需要多个线程访问LinkedList,则需要实现自己的同步机制。 只要未修改集合,LinkedList就可以同时支持多个读取器。即便如此,通过集合枚举本质上不是一个线程安全的过程。
ConcurrentLinkedList最初是在.NET 4的预览和测试版中引入的,但随后在.NET 4 RTM之前被删除,因为该类型强加了一种严格的编程模型,其性能优于锁定对链表的访问权限对于主要场景来说,不足以保证类型的包含。
您可以使用围绕关键部分的简单锁定机制实现自己的安全LinkedList<T>
。
答案 2 :(得分:0)
您不能立即使用LinkedList
进行多线程,因为它不是线程安全的集合。了解make it thread safe或建议如何选择thread safe collections之一。
答案 3 :(得分:0)
来自MSDN:此类型不是线程安全的。如果需要多个线程访问LinkedList,则需要实现自己的同步机制。