同步问题

时间:2012-02-15 14:18:33

标签: c# .net multithreading synchronization

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

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

bool b = false;

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

1 个答案:

答案 0 :(得分:5)

所以要求是:

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

所以代码看起来像:

public class Example
{
  private bool b = false;

  public void DoSomething()
  {
    if (!b)
    {
      b = true;
      DoExtraStuff();
    }
  }
}

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

你真的需要对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();
    }
  }
}

通过Interlocked.CompareExhange使用CAS操作有一种替代模式。不幸的是,没有超载会接受bool,但如果您愿意将bool更改为int,则以下内容也会有效。

public class Example
{
  private int b = 0;

  public void DoSomething()
  {
    if (Interlocked.CompareExchange(ref b, 0, 1) == 0)
    {
      DoExtraStuff();
    }
  }
}