我有一个可以从许多线程调用的方法,但我只是希望第一个线程在方法内部做一些逻辑。所以,我打算使用一个布尔变量。第一个进入的线程将布尔变量设置为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,那么第一个线程如何进入if执行方法逻辑,如果firstTime已经设置为false ??
我的问题是:如何锁定以获得所需的功能? (设置布尔和执行方法逻辑的第一个线程。)
我无法锁定所有方法逻辑,因为这将是一个非常耗时的操作。
答案 0 :(得分:7)
您可以使用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,1
表示false。
如果您想要使用0
而非lock
的解决方案,则可以通过使用其他本地Interlocked
值来实现:
bool