我在玩Thread,以提醒自己它们是如何工作的,很久以来我都没有做过Threading代码。
因此,我认为我将从最基本的示例开始,创建n个线程,让它们更新不带锁的静态int,这样我就可以看到它出错了。但是,它在起作用吗?每次的最终值是500,线程应同时更新该值,因此最终值应稍有随机性
我知道我在这里做的事很愚蠢,但我看不到
https://dotnetfiddle.net/w9TK5W
using System;
using System.Threading;
public class Program
{
public class Department
{
public static int a = 0;
public Department()
{
}
public void Inc()
{
a = a +5;
a = a -4;
}
}
public static void Main()
{
int count = 500;
Thread[] threads = new Thread[count];
Department dep = new Department();
for (int i = 0; i < count; i++)
{
Thread t = new Thread(new ThreadStart(dep.Inc));
threads[i] = t;
}
for (int i = 0; i < count; i++)
{
threads[i].Start();
}
Thread.Sleep(2000);
for (int i = 0; i < count; i++)
{
threads[i].Join();
}
Console.WriteLine(Department.a.ToString());
}
}
[编辑,更多信息]所以我将循环更改为如下所示,现在可以正常工作了
int b = a;
b = b+1;
int j=0;
for (int i=0; i<1E5; i++)
{
j += i;
}
a = b;
最佳答案
每个线程中的计算是如此之短,以至于每个启动的线程可能在下一个线程实际开始之前已经结束。
这是偶然的。
您应该在每个线程中运行一个对a
执行数百万次操作的循环,然后您可能会检测到预期的不一致。
该问题已通过数百万不更改a
的操作进行了编辑,因此,再次偶然地,实际上更改a
的极少数操作不会同时发生。
自上次发言以来,该问题已被编辑,但现在由于与预期的最初问题不同的原因而失败。
读取a
,稍等片刻,然后根据读取的值更改a
显然不是原子的。
如果循环仅执行a+=1
,那么您还可以看到这个看似微不足道的操作也不是原子的。
关于c# - C#线程示例代码在没有锁的情况下工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66294055/