以下代码如何自动线程安全?
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>
并在进行时构建字符串,则第二个任务可能会在第一个任务完成之前开始。
我有以下代码,其中两个线程正在向列表中添加新元素。
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>
并在进行时构建字符串,则第二个任务可能会在第一个任务完成之前开始。