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并且STILL由于某种原因进入循环。我不明白为什么。起初我以为可能是因为我创建的每个线程都在递增数组,但它不应该因为一个Thread有一个完整的独立执行路径,它应该直接跳转到CalcArray方法。
答案 0 :(得分:6)
发生这种情况的原因很微妙:当你这样做时
for(int i = 0; i < 5; i++) {
new Thread(() => CalcArray(i, arr)).Start();
}
变量i
经历值0一直到5,此时循环停止,因为5 < 5
计算为false
。
在循环结束后,线程启动,因此它看到的row
的值为5
,而不是0到4。
这可以通过在循环中创建局部变量row
来解决。
代码中的另一个问题是在繁忙的循环中检查thread_count
内的Main
而没有锁定。这不是与线程同步的最佳过程。请考虑改为使用ManualResetEventSlim
。