2010-09-14 98 views
0

我有一個從多線程調用的方法。每個線程都有自己的類實例。什麼是最直接的同步代碼訪問的方式?如何將多線程調用同步到同一方法

我不能僅僅使用lock(obj)其中obj是一個實例成員,但是在類上聲明obj爲靜態就足夠了嗎?所以對該方法的所有調用都會鎖定在同一個對象上?一個簡單的例子如下:

class Foo 
{ 
    static object locker = new object(); 

    public void Method() 
    { 
     lock(locker) 
     { 
      //do work 
     } 
    } 
} 

編輯://do work位被寫入到數據庫中。爲什麼我需要序列化這些寫入操作需要3頁才能解釋這個特殊情況,我真的不想重溫所有讓我明白這一點的細節。我所要做的就是確保每個記錄在寫完下一個記錄之前完成寫作。

+0

如果每個線程都有它們自己的類實例,如果它不觸及實例或全局之間共享的內容,則不需要鎖定對方法的調用。如果觸摸這樣的事情,也許這是他們應該鎖定的訪問權限,而不是整個方法。 – 2010-09-14 20:16:00

+0

你可以在http://www.albahari.com/threading/ – Patrick 2010-09-14 20:27:07

+3

瞭解很多有關C#線程(包括鎖)的知識。正確的同步方法是*解決由於錯誤同步引起的問題*的方法。您正在尋求解決方案,但沒有說明問題。 *你試圖解決的問題是什麼?例如,當另一個線程通過修改該狀態的一半時,一個線程是否會讀取不一致的狀態?是不是你可能觀察到在IA64上相互讀取和寫入亂序?說明你正試圖解決的問題,有人可以幫你解決問題;不要讓人猜測問題是什麼。 – 2010-09-14 21:04:46

回答

1

你的例子肯定會起作用,儘管必須有一些資源在類的不同實例中共享以實現必要的功能。

8

爲什麼你需要任何同步時線程每個都有自己的實例?保護共享資源,不要打擾未共享狀態。這會自動幫助您找到鎖定對象的最佳位置。如果它是對象有共同的靜態成員,那麼你的確需要一個靜態鎖定對象。

+0

+1:我完全同意。 – 2010-09-14 20:22:16

1

你忽略了最重要的部分:什麼數據參與// do work

如果// do work使用靜態數據,那麼你有正確的解決方案。

如果// do work只使用實例數據,那麼你可以離開了lock() {}完全(因爲1個實例屬於1個線程),或使用非靜態locker(1個實例,多線程)。