我希望您能提供有关在多个线程同时对
具体而言,请考虑以下人为构造的示例:
直觉告诉我,如果两个线程尝试写入位数组的相同基础整数值,则并发未锁定访问将产生不正确的结果。然而,我找不到任何支持它的证据,并且在运行时我也没有遇到任何问题。这是一个安全的操作吗?如果不是,为什么我没有看到此代码失败或产生不正确的输出?
更新:经过进一步测试,我认为以下测试证明在此示例中使用BitArray是不安全的。另一方面,使用bool[]似乎是安全的。
System.Collections.BitArray
类进行写入时,该类的线程安全性的信息。具体而言,请考虑以下人为构造的示例:
BitArray bits = new BitArray(1000000);
Parallel.For(0, bits.Count, i =>
{
bits[i] = i % 3 == 0;
});
直觉告诉我,如果两个线程尝试写入位数组的相同基础整数值,则并发未锁定访问将产生不正确的结果。然而,我找不到任何支持它的证据,并且在运行时我也没有遇到任何问题。这是一个安全的操作吗?如果不是,为什么我没有看到此代码失败或产生不正确的输出?
更新:经过进一步测试,我认为以下测试证明在此示例中使用BitArray是不安全的。另一方面,使用bool[]似乎是安全的。
private static bool CompareBitArrays(BitArray a, BitArray b)
{
if (a.Count != b.Count) return false;
for (int i = 0; i < a.Count; i++)
{
if (a[i] != b[i]) return false;
}
return true;
}
static void Main(string[] args)
{
int numElements = 1000000;
//create single-threaded bitarray with certifiably correct values.
BitArray controlGroup = new BitArray(numElements);
for (int i = 0; i < numElements; i++)
{
controlGroup[i] = i % 3 == 0;
}
//create a BitArray and bool array of equal size and fill them using Parallel.For.
BitArray bits = new BitArray(numElements);
bool[] bools = new bool[numElements];
Parallel.For(0, numElements, i =>
{
bits[i] = bools[i] = i % 3 == 0;
});
//Create a BitArray from the bool array
BitArray boolBits = new BitArray(bools);
//Check if they contain correct values
bool isBitArrayCorrect = CompareBitArrays(controlGroup, bits); //FALSE
bool isBoolArrayCorrect = CompareBitArrays(controlGroup, boolBits); //TRUE
}
正如我之前提到的,我怀疑问题原因是BitArray
中32个值共享数组的同一整数值。
这个逻辑正确吗?
出于问题的考虑,请假设除了代码中显示的线程之外,没有其他线程访问该集合。
Parallel.For
循环中向集合写入内容。((i % 3) == 0)的结果被写入到集合中的Bit[i]
。因此这是一种修改操作,需要同步。 - Tony The Lionbool[]
数组同样不安全吗? - Rotem