c# - C#线程示例代码在没有锁的情况下工作

标签 c# multithreading

我在玩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/

相关文章:

ios - iPad : need accurate alternative to NSTimer for making donkey kong style game

c# - 如何知道文本是否大于文本框?

c# - 异步/等待中的重入?

c# - 调用跨域URL时,HttpWebRequest响应始终为text/html

c++ - 终止正在运行的线程 c++ std::thread

c++ - Libuv:保护事件循环免受并发访问

c - thread和process id的取值范围是多少?

java - 使用执行器服务等待守护线程完成迭代

c#富文本框如何在winform中设置文本边距

c# - 解决方案中存在冲突的对象名称