如何锁定方法内容

本文关键字:方法 锁定 何锁定 | 更新日期: 2023-09-27 18:27:07

我有一个可以从多个线程调用的方法,但我只希望第一个线程在该方法中执行一些逻辑。所以,我打算使用一个布尔变量。进入的第一个线程将布尔变量设置为false(以防止更多线程进入),并执行方法逻辑。

使用此方法的后续线程将检查布尔变量。因为它被第一个线程设置为false,所以他们将跳过方法逻辑。

在代码中,类似这样的东西:

private void myMethod()
{
   if (firsTime)  //set to true in the constructor
   {
      firstTime = false; //To prevent other thread to come inside here.
      //method logic
   }
}

我想使用锁来执行此操作,但不确定将其放在哪里。

如果我锁定在"If"内部以将firstTime更改为false,则可能有2个或更多线程已经进入If内部(不希望这样)。

如果我在"If"外部锁定以将firstTime更改为false,那么如果firstTime已经设置为false,第一个线程如何进入If内部执行方法逻辑??

我的问题是:如何使锁具有所需的功能?(第一个线程设置布尔值并执行方法逻辑)。

我无法锁定所有的方法逻辑,因为这将是一个非常耗时的操作。

如何锁定方法内容

您可以使用Interlocked.Exchange来解决此问题。它会将给定变量的值设置为指定的值,并返回该变量中的值,并且它将以原子的方式完成所有操作。这样做将确保只有一个线程在if:中运行代码

private static int isFirst = 1;
public static void Foo()
{
    if (Interlocked.Exchange(ref isFirst, 0) == 1)
    {
        //DoStuff
    }
}

请注意,Interlocked.Exchange没有使用bool的重载,这就是为什么您被迫使用int(或其他类型),使用1表示true,0表示false。

如果您想要使用lock而不是Interlocked的解决方案,您可以通过使用额外的本地bool值来实现:

private static bool isFirst = true;
private static object key = new object();
public static void Foo()
{
    bool amFirst;
    lock (key)
    {
        amFirst = isFirst;
        isFirst = false;
    }
    if (amFirst)
    {
        //DoStuff
    }
}