同步问题

Pin*_*lim 1 .net c# multithreading synchronization

我的代码中有以下场景(C#.NET 4):

我有一个初始化为false的布尔变量:

bool b = false;
Run Code Online (Sandbox Code Playgroud)

现在我正在实例化线程数,每个线程都需要读取b的值.第一个读取b的线程 - 应该将其值更改为true(并执行一些逻辑...),其他线程应该什么都不做.我是否需要在读取其值时使用"b"同步机制,或者只能在将其值设置为true时锁定它?这应该会提升我的表现,但我想知道它的安全性.

Bri*_*eon 5

所以要求是:

  • 多个线程读取单个bool变量
  • 如果一个线程看到一个false值,它应该将其更改为true并执行其他工作
  • 如果线程看到一个true值,则不会发生其他任何事情
  • 只有一个线程应该能够更改值并执行其他工作

所以代码看起来像:

public class Example
{
  private bool b = false;

  public void DoSomething()
  {
    if (!b)
    {
      b = true;
      DoExtraStuff();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,如果有多个线程正在执行DoSomething,并且意图DoExtraStuff只应该执行一次,那么这是不安全的.问题是线程将在读写时竞争b.

你真的需要对read进行读写b.这可以使用lock关键字完成.

public class Example
{
  private bool b = false;
  private object locker = new object();

  public void DoSomething()
  {
    bool trigger = false;
    lock (locker)
    {
      if (!b)
      {
        b = true;
        trigger = true;
      }
    }

    if (trigger)
    {
      DoExtraStuff();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

有一种使用CAS操作的替代模式Interlocked.CompareExhange.不幸的是,没有超载接受a bool,但是如果你愿意将其bool改为int以下也可以.

public class Example
{
  private int b = 0;

  public void DoSomething()
  {
    if (Interlocked.CompareExchange(ref b, 0, 1) == 0)
    {
      DoExtraStuff();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)