我需要做一些要求读取线程中arrey的每个元素的东西。
每个线程只需要读取元素[i]
并执行i++
。我需要锁定i++
吗?
我在某处读到了带有双变量的异步操作需要锁定以防止意外结果。我怎么能对另一个操作说同样的话?以下是有问题的操作列表吗?
更多细节。我有全局变量:
public static int[] IntArray;
public static int ArrayPointer = 0;
我以这种方式在池中启动一些线程:
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod));
像这样:
static void ThreadMethod() {
//loop until ArrayPointer is too big
Console.WriteLine(IntArray[ArrayPointer]);
ArrayPointer++;
//end of loop
}
答案 0 :(得分:5)
这里重点是你有一个共享变量,++
运算符执行读/修改/写操作。该操作不原子,即使它的每个部分都是。
所以你可以轻松拥有:
Thread 1 Thread 2
Read ArrayPointer (0)
Read ArrayPointer(0)
Increment locally (1)
Increment locally (1)
Write ArrayPointer (1)
Write ArrayPointer (1)
所以尽管有两个增量,你的结果是1。
您可以使用Interlocked.Increment
以原子方式递增,但您仍然希望在循环的其余迭代中使用该递增操作的结果,而不是多次读取该变量。
我实际上会在这里提出三件事:
答案 1 :(得分:1)
该死的,这是非常明显的,因为另一个线程可以突然执行i++
并且数组的某些元素将被滑落。
所以只是:
static void ThreadMethod() {
//loop until ArrayPointer is too big
lock(LockObject) {
Console.WriteLine(IntArray[ArrayPointer]);
ArrayPointer++;
}
//end of loop
}