C# 多线程成员变量与静态变量,它们在多线程中的工作方式如何不同?

C# 多线程成员变量与静态变量,它们在多线程中的工作方式如何不同?,c#,multithreading,C#,Multithreading,我对成员变量和静态变量做了一个快速测试,我发现了一个有趣的结果,如果一个变量是静态对象的成员变量,即使在线程竞赛的上下文中也总是正确计算,但是如果一个变量是静态变量,它将遇到问题 例如: 类程序 { 静态void Main(字符串[]参数) { var locker=新对象(); SetMaxThreads(64,64); var numOfThreads=64; WaitHandle[]waitHandles=新的WaitHandle[numOfThreads]; var sw=新秒表()

我对成员变量和静态变量做了一个快速测试,我发现了一个有趣的结果,如果一个变量是静态对象的成员变量,即使在线程竞赛的上下文中也总是正确计算,但是如果一个变量是静态变量,它将遇到问题

例如:

类程序
{
静态void Main(字符串[]参数)
{
var locker=新对象();
SetMaxThreads(64,64);
var numOfThreads=64;
WaitHandle[]waitHandles=新的WaitHandle[numOfThreads];
var sw=新秒表();
sw.Start();
对于(长i=0;i
{
obj.run();
((EventWaitHandle)handle.Set();
},手柄);
//obj.run();
}
WaitHandle.WaitAll(waitHandles);
sw.Stop();
WriteLine($“退出性能测试{sw.elapsedmillisons}输出:{obj.x}”);
Console.ReadKey();
}
静态MyClass obj=新MyClass();
}
类MyClass
{
私有对象锁定器=新对象();
//公共静态int x=0;
公共整数x=0;
公开募捐{
//锁(储物柜)
{
对于(int j=0;j<10000000;j++)
{
x=x+1;
}
WriteLine($“id:{Thread.CurrentThread.ManagedThreadId},循环计数:{x}”);
}
var f=0;
WriteLine($“id:{Thread.CurrentThread.ManagedThreadId},$$start:{f}”);
对于(int j=0;j<10000000;j++)
{
f=f+1;
}
WriteLine($“id:{Thread.CurrentThread.ManagedThreadId},$$end:{f}”);
}
}
据我所知,静态对象及其成员字段在内存中有一个实例副本,由多线程共享,因此它应该与使用静态变量相同,但不知何故,它的行为不同

问题: 1.多线程中静态字段和成员字段的区别是什么? 2.这是否意味着静态字段的运行速度比成员字段快

谢谢

  • 多线程中静态字段和成员字段的区别是什么? 我发现对于小循环成员字段几乎不会遇到多线程竞速问题,但是对于大循环10000000,它们都会遇到竞速问题,因此它们都需要使用locker

  • 这是否意味着静态字段的运行速度比成员字段快? 我发现使用locker比不使用locker写入共享资源更快


  • 在这种情况下,可以使用Interlocked.Increment。对于更复杂的类型,请使用锁或其他线程同步方法,以避免多个线程并行使用共享资源。请不要发布代码截图-发布代码本身。@Evk确定我会这样做。我尝试运行您的代码,无论
    x
    是否为静态,我都有相同的行为。您确定在使用静态成员进行测试时没有取消注释
    lock(locker)
    语句吗?
    class Program
    {
    
        static void Main(string[] args)
        {
            var locker = new object();
            ThreadPool.SetMaxThreads(64, 64);
            var numOfThreads = 64;
    
    
            WaitHandle[] waitHandles = new WaitHandle[numOfThreads];
    
            var sw = new Stopwatch();
            sw.Start();
            for (long i = 0; i < numOfThreads; i++)
            {
                var handle = new EventWaitHandle(false, EventResetMode.ManualReset);
                waitHandles[i] = handle;
                ThreadPool.QueueUserWorkItem((state) =>
                {
    
                    obj.run();
                    ((EventWaitHandle)handle).Set();
                }, handle);
                //obj.run();
            }
            WaitHandle.WaitAll(waitHandles);
            sw.Stop();
    
    
            Console.WriteLine($"Exit Performance test {sw.ElapsedMilliseconds} output: {obj.x}");
            Console.ReadKey();
        }
        static MyClass obj = new MyClass();
    }
    
    class MyClass
    {
        private object locker = new object();
        //public static int x = 0;
        public int x = 0;
        public void run() {
            //lock (locker)
            {
                for (int j = 0; j < 10000000; j++)
                {
                    x = x + 1;
                }
    
                Console.WriteLine($"id: {Thread.CurrentThread.ManagedThreadId}, count of loop: {x}");
            }
            var f = 0;
            Console.WriteLine($"id: {Thread.CurrentThread.ManagedThreadId}, $$start: {f}");
            for (int j = 0; j < 10000000; j++)
            {
                f = f + 1;
            }
            Console.WriteLine($"id: {Thread.CurrentThread.ManagedThreadId}, $$end: {f}");
    
        }
    }