以下代码中是否存在可能的比赛条件?
public void Process(List<SomeObject> list)
{
SomeDataOutput objData=null;
ConcurrentBag<SomeDataOutput> cbOutput = new ConcurrentBag<SomeDataOutput>();
ParallelOptions po = new ParallelOptions(){MaxDegreeOfParallelism=4};
Parallel.ForEach(list, po, (objInput) =>
{
objData = GetOutputData(objInput);//THIS LINE IS THE ONE I AM UNSURE OF. CAN objData GET OVERWRITTEN BY MULTIPLE PARALLEL THREADS?
cbOutput.Add(objData);
});
}
最佳答案
是的,有一个可能的比赛条件。两个线程可以交错循环体中的语句,如下所示:
Thread #1 Thread #2
================================== ==================================
objData = GetOutputData(objInput);
objData = GetOutputData(objInput);
cbOutput.Add(objData);
cbOutput.Add(objData);
因为
objData
是在循环外部声明的,所以两个线程共享同一个变量。结果,thread 2重写thread 1设置的objData
引用,thread 2的objData
被添加到cbOutput
两次。要防止
objData
被多个线程共享,请将其设置为局部变量:SomeDataOutput objData = GetOutputData(objInput);
cbOutput.Add(objData);
或者您可以完全去掉变量:
cbOutput.Add(GetOutputData(objInput));