我编写这个实验是为了向某人证明使用多个线程同时访问共享数据是一个很大的禁忌。令我惊讶的是,无论我创建了多少线程,我都无法创建并发问题,并且该值始终导致平衡值 0。我知道增量运算符不是线程安全的,这就是为什么有方法像Interlocked.Increment()
和Interlocked.Decrement()
(这里也注意到++ 运算符线程安全吗?)。
如果递增/递减运算符不是线程安全的,那么为什么下面的代码执行时没有任何问题并且结果达到预期值?
下面的代码片段创建了 2,000 个线程。1,000 不断增加和 1,000 不断减少,以确保多个线程同时访问数据。更糟糕的是,在普通程序中,您不会拥有几乎一样多的线程。然而,尽管为了创建并发问题而夸大了数字,但该值始终导致平衡值为 0。
static void Main(string[] args)
{
Random random = new Random();
int value = 0;
for (int x=0; x<1000; x++)
{
Thread incThread = new Thread(() =>
{
for (int y=0; y<100; y++)
{
Console.WriteLine("Incrementing");
value++;
}
});
Thread decThread = new Thread(() =>
{
for (int z=0; z<100; z++)
{
Console.WriteLine("Decrementing");
value--;
}
});
incThread.Start();
decThread.Start();
}
Thread.Sleep(TimeSpan.FromSeconds(15));
Console.WriteLine(value);
Console.ReadLine();
}
我希望有人能给我一个解释,以便我知道我编写线程安全软件的所有努力都没有白费,或者这个实验在某种程度上存在缺陷。我还尝试了所有线程递增并使用 ++i 而不是 i++。该值始终会产生预期值。