首页 > 代码库 > C# Interlocked类的使用

C# Interlocked类的使用

在C#中,赋值和简单的数字运算都不是原子型操作。在多线程环境下,会产生数据安全的问题。


在多线程环境下,我们可以通过使用System.Threading.Interlocked类来实现原子型操作当个数据,使用它比使用Monitor类跟简单。


Interlocked类主要方法

方法
作用
CompareExchange()
安全比较两个值是不是相等。如果相等,将第三个值于其中一个值交换
Decrement()
安全递减1,相当于 i--
Exchange()
安全交换数据,相当于 a = 30
Increment()
安全递加1,相当于 i++
Add()
安全相加一个数值,相当于 a = a + 3
Read()
安全读取数值,相等于int a=b


例子1:

private int value1 = 0;
        public void TestIncrementUnSafe()
        {
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(IncrementValue1);
                t.Name = "t1 " + i;
                t.Start();
            }
            Thread.Sleep(2000);
            //value maybe 500000
            Console.WriteLine("value1 = " + value1);
        }
        private int value2 = 0;
        public void TestIncrementSafe()
        {
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(IncrementValue2);
                t.Name = "t2 " + i;
                t.Start();
            }
            Thread.Sleep(2000);
            //value should be 500000
            Console.WriteLine("value2 = " + value2);
        }
        private void IncrementValue1()
        {
            for (int i = 0; i < 1000000; i++)
            {
                value1++;
                //Console.WriteLine(Thread.CurrentThread.Name);
            }
        }
        private void IncrementValue2()
        {
            for (int i = 0; i < 1000000; i++)
            {
                Interlocked.Increment(ref value2);
            }
        }

控制台输出:

运行结果1

value1 = 4612592
value2 = 5000000

运行结果2

value1 = 4697979
value2 = 5000000


例子2

private int value3 = 0;
        public void TestExchangeSafe()
        {
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(ExchangeValue3);
                t.Name = "t2 " + i;
                t.Start();
            }
            Thread.Sleep(2000);
            //value should be 83
            Console.WriteLine("value3 = " + value3);
        }
        private void ExchangeValue3()
        {
            Interlocked.Exchange(ref value3, 83);
        }
        private int value4 = 0;
        public void TestCompareExchangeSafe()
        {
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(ExchangeValue3);
                t.Name = "t2 " + i;
                t.Start();
            }
            Thread.Sleep(2000);
            //value should be 99 or 0
            Console.WriteLine("value4 = " + value4);
        }
        private void ExchangeValue4()
        {
            //if value4=0, set value4=99
            Interlocked.CompareExchange(ref value4, 99,0);
        }

控制台输出:

value4 = 0
value3 = 83