in

SDT Community Server

SDT Forums, Blogs, Photos server.

wego

March 2007 - Posts

  • 一个小小的C#语句 i++; 也会操作不成功 !

    前提在运行多线程前提下.

    因为在大多数计算机上,增加变量操作不是一个原子操作,需要执行下列步骤:

    1. 将实例变量中的值加载到寄存器中。
    2. 增加或减少该值。
    3. 在实例变量中存储该值。

    如果不使用 Interlocked  类的 IncrementDecrement,线程会在执行完前两个步骤后被抢先。然后由另一个线程执行所有三个步骤。当第一个线程重新开始执行时,它改写实例变量中的值,造成第二个线程执行增减操作的结果丢失。

    请见如下例子: 
    using System;
    using System.Threading;
    
    class Test
    {
        static void Main()
        {
            Thread thread1 = new Thread(new ThreadStart(ThreadMethod));
            Thread thread2 = new Thread(new ThreadStart(ThreadMethod));
            thread1.Start();
            thread2.Start();
            thread1.Join();
            thread2.Join();
    
            // Have the garbage collector run the finalizer for each
            // instance of CountClass and wait for it to finish.
            GC.Collect();
            GC.WaitForPendingFinalizers();
    
            Console.WriteLine("UnsafeInstanceCount: {0}" +
                "\nSafeCountInstances: {1}",
                CountClass.UnsafeInstanceCount.ToString(),
                CountClass.SafeInstanceCount.ToString());
        }
    
        static void ThreadMethod()
        {
            CountClass cClass;
            
            // Create 100,000 instances of CountClass.
            for(int i = 0; i < 100000; i++)
            {
                cClass = new CountClass();
            }
        }
    }
    
    class CountClass
    {
        static int unsafeInstanceCount = 0;
        static int   safeInstanceCount = 0;
    
        static public int UnsafeInstanceCount
        {
            get {return unsafeInstanceCount;}
        }
    
        static public int SafeInstanceCount
        {
            get {return safeInstanceCount;}
        }
    
        public CountClass()
        {
            unsafeInstanceCount++;
            Interlocked.Increment(ref safeInstanceCount);
        }
    
        ~CountClass()
        {
            unsafeInstanceCount--;
            Interlocked.Decrement(ref safeInstanceCount);
        }
    }
    
Copyright SDT, 2006-2009. All rights reserved.