以下代码如何自动线程安全?

How is the following code automatically thread safe?

我有以下代码,其中两个线程正在向列表中添加新元素。

public class Numbers
        {
            public int number;
            public string threadName;
        }
        static void Main(string[] args)
        {

            List<Numbers> numbers = new List<Numbers>();

            Task t = Task.Factory.StartNew(() => {
                for (int i = 0; i < 999; i++)
                {
                    numbers.Add(new Numbers() { number = i, threadName = "t" });

                }
            });
            Task k = Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 999; i++)
                {
                    numbers.Add(new Numbers() { number = i, threadName = "k" });
                }
            });


            t.Wait();
            k.Wait();


            StreamWriter writer = new StreamWriter("text.txt");

            foreach (var item in numbers)
            {
                writer.WriteLine(item.threadName + item.number);
            }
            writer.Flush();
            Console.WriteLine("Done!");
            Console.ReadLine();
        }

当我打开文本文件时,我看到它们与 k0k1...k999t0t1...t999 完美对齐。但我原以为名单会被混合或改组。为什么这两个任务不是随机添加新元素,而是完美排序?

您的任务绝对不是线程安全的,因为它们同时写入同一个列表。您得到您看到的结果的最可能原因是第一个任务完成得非常快 - 它在第二个任务有机会开始之前完成了所有 999 个对象的写入。

如果您在执行任务时添加一个随机的短暂延迟,您会看到结果有些随机性。让您的任务完成更多工作也可能会增加一些随机性:例如,如果您将列表设为 List<string> 并在进行时构建字符串,则第二个任务可能会在第一个任务完成之前开始。