C# 线程..不明白为什么我的循环是 5;

本文关键字:循环 我的 为什么 线程 明白 | 更新日期: 2023-09-27 18:30:23

class Thread1_8
{
    static int shared_total;
    static int thread_count;
    static readonly object locker = new object();
    static void Main()
    {
        int[,] arr = new int[5, 5] { { 1,2,3,4,5}, {5,6,7,8,9}, {9,10,11,12,13}, {13,14,15,16,17}, { 17,18,19,20,21} };
        for(int i = 0; i < 5; i++)
        {
            new Thread(() => CalcArray(i, arr)).Start();
        }

        while(thread_count < 5)
        {
        }
        Console.WriteLine(shared_total);
    }
    static void CalcArray(int row, int[,] arr)
    {
        int length = arr.GetLength(0);
        int total = 0;
        for(int j = 0; j < length; j++)
        {
           total += arr[row,j];
        }
        lock (locker)
        {
            shared_total += total;
            thread_count++;
        }
    }
}

我不断得到一个System.IndexOutOfRangeException。

原因是由于某种原因,我在初始 for 循环中的"i"被设置为 5,并且由于某种原因仍然进入循环。我不明白为什么。起初我认为这可能是因为我创建的每个线程都在递增数组,但不应该,因为线程具有完整的单独执行路径,它应该直接跳转到 CalcArray 方法。

C# 线程..不明白为什么我的循环是 5;

发生这种情况的原因很微妙:当你这样做时

for(int i = 0; i < 5; i++) {
    new Thread(() => CalcArray(i, arr)).Start();
}

变量 i 从值 0 一直到 5,此时循环停止,因为5 < 5计算结果为 false

线程在循环结束后启动,因此它看到的row值是 5 ,而不是 0 到 4。

这可以通过在循环内row局部变量来解决。

代码中的另一个问题是在繁忙的循环中检查Main内部的thread_count而不锁定。这不是与线程同步的最佳过程。请考虑改用ManualResetEventSlim