2025-03-26 00:02:56 +08:00

4.6 KiB

#unity/日常积累

Interlocked 类

  • 参考

定义

命名空间:

System.Threading

程序集:

System.Threading.dll

为多个线程共享的变量提供原子操作。

public static class Interlocked

继承

Object

Interlocked

示例

下面的代码示例演示线程安全资源锁定机制。

using System;
using System.Threading;

namespace InterlockedExchange_Example
{
    class MyInterlockedExchangeExampleClass
    {
        //0 for false, 1 for true.
        private static int usingResource = 0;

        private const int numThreadIterations = 5;
        private const int numThreads = 10;

        static void Main()
        {
            Thread myThread;
            Random rnd = new Random();

            for(int i = 0; i < numThreads; i++)
            {
                myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Thread{0}", i + 1);
            
                //Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000));
                myThread.Start();
            }
        }

        private static void MyThreadProc()
        {
            for(int i = 0; i < numThreadIterations; i++)
            {
                UseResource();
            
                //Wait 1 second before next attempt.
                Thread.Sleep(1000);
            }
        }

        //A simple method that denies reentrancy.
        static bool UseResource()
        {
            //0 indicates that the method is not in use.
            if(0 == Interlocked.Exchange(ref usingResource, 1))
            {
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);
            
                //Code to access a resource that is not thread safe would go here.
            
                //Simulate some work
                Thread.Sleep(500);

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);
            
                //Release the lock
                Interlocked.Exchange(ref usingResource, 0);
                return true;
            }
            else
            {
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
                return false;
            }
        }
    }
}

注解

此类的方法有助于防止当计划程序切换上下文时,当线程更新可由其他线程访问的变量时,或者当两个线程同时在单独的处理器上执行时,可能会出现的错误。 此类的成员不会引发异常。

DecrementIncrement方法递增或递减变量,并将结果值存储在单个操作中。 在大多数计算机上,递增变量不是原子操作,需要以下步骤:

  1. 将实例变量的值加载到寄存器中。

  2. 递增或递减值。

  3. 将值存储在实例变量中。

如果不使用 Increment 并且 Decrement执行前两个步骤后,可以抢占线程。 然后,另一个线程可以执行所有三个步骤。 当第一个线程恢复执行时,它会覆盖实例变量中的值,并丢失第二个线程执行的递增或递减的效果。

该方法 Add 以原子方式将整数值添加到整数变量,并返回该变量的新值。

该方法 Exchange 以原子方式交换指定变量的值。 该方法 CompareExchange 结合两个操作:根据比较的结果,比较两个值,并将第三个值存储在其中一个变量中。 比较和交换操作作为原子操作执行。

确保对共享变量的任何写入或读取访问权限都是原子的。 否则,数据可能会损坏,或者加载的值可能不正确。