2008-12-19 74 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

更糟糕的是,鎖定只讀結構是創建死鎖的好方法。