【问题标题】:Do I need to lock "read only" services when using threading?使用线程时是否需要锁定“只读”服务?
【发布时间】:2008-12-19 22:01:07
【问题描述】:

我正在重写一项服务以使用线程。我知道来自一个线程的状态不应该被另一个线程访问,但是我对什么构成“状态”有点困惑。这是否意味着 任何 方法范围之外的字段/属性/方法?

具体来说,我的服务看起来像这样:

public class MyService
{
      private IRepository<MyClass> repository;
      private ILogger log;
      ...
      public void MyMethod()
      {
        ...
        var t = new Thread(MyMethodAsync);
        t.Start(someState);
      }

      //Is this OK???
      public void MyMethodAsync(object state)
      {
          var someState = (MyState)state;
          log.Log("Starting");
          var someData = repository.GetSomeData(someState.Property);
          //process data
          log.Log("Done");            
      }

      //Or should I be doing this:
      public void MyMethodAsync2(object state)
      {
          var someState = (MyState)state;
          lock(log){
             log.Log("Starting");  }

          lock(repository){         
             var someData = repository.GetSomeData(someState.Property);}

          //process data   
          lock(log){
             log.Log("Done"); }            
      }
}

【问题讨论】:

    标签: c# multithreading


    【解决方案1】:

    呃...不,您不需要锁定只读资源。锁定它们的目的是,如果您需要在写入资源之前检查它的值,那么另一个资源不能在您的读取和写入之间更改值。即:

    SyncLock MyQueue
      If MyQueue.Length = 0 Then
        PauseFlag.Reset
      End If
    End SyncLock
    

    如果我们在设置标志以暂停进程队列线程之前检查队列的长度,然后另一个资源将向队列添加项目,那么我们的进程队列线程将处于暂停状态,而在检查队列长度和设置暂停标志之间可能已经添加了项目...

    如果所有资源都只是以只读方式访问队列(我不能想到一个只读队列的有用应用程序),那么就没有必要锁定它。

    【讨论】:

      【解决方案2】:

      “状态”是类中包含的所有数据,就并发而言,真正的问题是写访问,所以你的直觉是正确的。

      【讨论】:

        【解决方案3】:

        更糟糕的是,锁定只读结构是创建死锁的好方法。

        【讨论】:

          猜你喜欢
          • 2021-12-19
          • 2011-02-23
          • 2021-09-28
          • 2012-02-19
          • 1970-01-01
          • 2013-12-07
          • 1970-01-01
          • 2013-03-15
          相关资源
          最近更新 更多