简体   繁体   English

不是线程安全的-公共静态列表<T>

[英]Not thread safe - public static List<T>

I was reading in MSDN that a List is thread safe when used as a public static type . 我在MSDN中读到,List用作公共静态类型时是线程安全的。 However the following code snippet proves otherwise. 但是,以下代码段证明不是这样。 I am trying to add and remove elements from the list but the remove method throws an error midway saying index out of bounds. 我正在尝试从列表中添加和删除元素,但是remove方法在途中抛出一个错误,说索引超出范围。 What is going wrong here? 这是怎么了?

Is this a right implementation to check my theory. 这是检查我的理论的正确实现。 If not, can someone please suggest a better example. 如果没有,请有人提出一个更好的例子。

class Program
{
    public static List<string> strlist = new List<string>();
    public static AutoResetEvent autoEvent = new AutoResetEvent(false);
    static void Main(string[] args)
    {

        strlist = new List<string>();
        new Thread(() => 
        {

            for(int i=0;i<10000000;i++)
            {
         strlist.Add("item1");
            }
            //Thread.Sleep(5000);
            autoEvent.Set();
        }).Start(); ;

        new Thread(() => {

         strlist.ForEach(e => strlist.Remove(e));

        }).Start();

        Console.WriteLine("Waiting");
        autoEvent.WaitOne();
        int ci = 0;

        strlist.ForEach(str => ci++);
        Console.WriteLine(ci.ToString() + " Done");
        Console.Read();


    }

}

I was reading in MSDN that a List is thread safe when used as a public static type. 我在MSDN中读到,用作公共静态类型时,列表是线程安全的。

That statement is not true. 那句话是不正确的。 You probably are referring to this text: 您可能是指此文本:

Public static members of this type are thread safe. 此类型的公共静态成员是线程安全的。

That refers to members of the class List<T> . 这指的是类的成员 List<T> It does not refer to instances of the class List<T> . 不是指该类的实例 List<T>

Your reading was incorrect. 您的阅读不正确。 You are using instance members ( .Add() etc); 您正在使用实例成员( .Add()等); instance members are not thread-safe; 实例成员不是线程安全的; MSDN is explicit about this. MSDN 对此是明确的。

Thread Safety 线程安全

Public static (Shared in Visual Basic) members of this type are thread safe. 此类型的公共静态(在Visual Basic中为Shared)成员是线程安全的。 Any instance members are not guaranteed to be thread safe. 不保证任何实例成员都是线程安全的。

A List<T> can support multiple readers concurrently, as long as the collection is not modified. 只要不修改集合, List<T>就可以同时支持多个阅读器。 Enumerating through a collection is intrinsically not a thread-safe procedure. 通过集合进行枚举本质上不是线程安全的过程。 In the rare case where an enumeration contends with one or more write accesses, the only way to ensure thread safety is to lock the collection during the entire enumeration. 在极少数情况下,枚举与一个或多个写访问竞争,确保线程安全的唯一方法是在整个枚举期间锁定集合。 To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization. 要允许多个线程访问该集合以进行读写,您必须实现自己的同步。

In fact, List<T> doesn't have any static methods (the text merely asserts the default: static members are usually thread-safe; instance members are usually not thread-safe) 实际上, List<T> 没有任何静态方法(文本仅声明默认值:静态成员通常是线程安全的;实例成员通常不是线程安全的)

I think when they said "static" they didn't mean you have to use static keyword and everything works. 我认为当他们说“静态”时,并不意味着您必须使用static关键字,并且一切正常。 They meant that as long as the list is static, as in "it never gets modified in any way," then you can use it from multiple threads without any problems. 他们的意思是,只要列表是静态的(如“绝不以任何方式修改它”),那么您就可以在多个线程中使用它,而不会出现任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM