简单的C#并发/多线程

Tal*_*Tal 5 c# multithreading

我可能在这里遗漏了一些基本的东西,但仍然很感谢你在理解这一点时给予的帮助.所以我写了以下简单的多线程程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //            List<int> outcome = new List<int>();
            Test t = new Test();

                Thread thread1 = new Thread(new ThreadStart(t.call1));
                Thread thread2 = new Thread(new ThreadStart(t.call2));
                thread1.Start();
                thread2.Start();
                Thread.Sleep(3000); //Give enough time for threads to end
                Console.Write("{0},", t.mSum);
                t.mSum = 0;
        }
    }

    class Test
    {
        public int mSum = 0;
        public void call1()
        {
            //lock (this)
            //{

            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine("Hello Thread 1, mSum value: {0}", mSum);
                mSum = mSum + 1;
                Console.WriteLine("Goodbye Thread 1, mSum value: {0}", mSum);
            }
            //}
            //  Console.WriteLine(mSum);
        }
        public void call2()
        {
            for (int i = 0; i < 100 ; i++)
            {
                Console.WriteLine("Hello Thread 2, mSum value: {0}",mSum);
                mSum = mSum + 1;
                Console.WriteLine("Goodbye Thread 2, mSum value: {0}",mSum);
            }
        }
    }
}    
Run Code Online (Sandbox Code Playgroud)

所以我希望这个输出是不可能的,因为上下文切换可以随时发生吗?但是当我运行该程序时,我得到以下输出(只有部分输出,由于我的stackoverflow.com问题发布技巧不佳而导致格式错误):

Hello Thread 1, mSum value: 62    Goodbye Thread 1, mSum value: 63   
Hello Thread 1, mSum value: 63    Goodbye Thread 1, mSum value: 64   
Hello Thread 2, mSum value: 59    Goodbye Thread 2, mSum value: 65   
Hello Thread 2, mSum value: 65    Goodbye Thread 2, mSum value: 66

所以,假设我写得正确,并且mSum确实在线程之间共享(看起来像......) - 我该如何解释行号.3?线程2读取59,加1,然后我们得到65!

我发现了一种新的数学吗?:)

Bar*_*zKP 9

您没有锁定共享变量mSum,mSum = mSum + 1也不是原子操作.显而易见的是,打印到控制台,递增变量然后再次打印到控制台并不是原子的:)线程可能有许多可能的交错方式.例如:

1)mSum = 0 [Thread1正在工作]

2)mSum = 1 [Thread1正在工作]

3)mSum = 2 [Thread2正在工作]

4)......

5)mSum = 59 [Thread2正在工作]并在"你好......"之后被抢先一步

6)mSum = 60 [Thread1正在工作]

7)mSum = 61 [Thread1正在工作]

8)......

9)mSum = 64 [Thread2工作]在增量线Thread2继续之前唤醒,并计算65

5) Thread2可能已经捷足先登,即使在读取内存MSUM之后mSum = mSum + 1,但在计算前mSum + 1.