2008-12-19 71 views
1

我有一个服务,我正在重写使用线程。我明白,一个线程的状态不应该被另一个线程访问,但是我对“状态”的构成有点困惑。这是否意味着在方法范围之外的任何字段/属性/方法?使用线程时,我需要锁定“只读”服务吗?

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

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"); }    
     } 
} 

回答

1

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

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

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

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

2

“国家”是包含在类的所有数据,并尽可能并发去真正的问题是写访问,所以你的直觉是正确的。

0

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