多线程向LinkedList添加节点?

时间:2014-10-21 09:14:22

标签: c# .net

例如我有var linkedList = new LinkedList<int>();

然后我添加一个节点。 linkedList.AddLast(1);

之后我有两个线程分别调用linkedList.AddLast(2);(同一语句)。

我可以安全地预期它会变成1-> 2&gt; 2链表吗?

或者当竞争条件发生时它可以变成1-> 2?

(也许它也有可见性问题,但在此之前我首先想知道这种竞争条件是否会发生。)

4 个答案:

答案 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

  

此类型不是线程安全的。如果需要多个线程访问LinkedList,则需要实现自己的同步机制。   只要未修改集合,LinkedList就可以同时支持多个读取器。即便如此,通过集合枚举本质上不是一个线程安全的过程。

Stephan Toub在他的一个答案中说:

  

ConcurrentLinkedList最初是在.NET 4的预览和测试版中引入的,但随后在.NET 4 RTM之前被删除,因为该类型强加了一种严格的编程模型,其性能优于锁定对链表的访问权限对于主要场景来说,不足以保证类型的包含。

您可以使用围绕关键部分的简单锁定机制实现自己的安全LinkedList<T>

答案 2 :(得分:0)

您不能立即使用LinkedList进行多线程,因为它不是线程安全的集合。了解make it thread safe或建议如何选择thread safe collections之一。

答案 3 :(得分:0)

来自MSDN:此类型不是线程安全的。如果需要多个线程访问LinkedList,则需要实现自己的同步机制。