簡體   English   中英

C#中的鎖定范圍:返回的對象是否仍然“鎖定”?

[英]Lock scope in C#: is returned object still “locked”?

假設我有一個包含的對象A.

// ...

private List<double> someList = new List<double>();

// ... 

public List<double> SomeList
{
    get { lock (this) { return someList; } }
}

// ...

在下面的代碼中對列表執行操作是否是線程安全的。 知道幾個操作可以由不同的線程同時執行。

A.SomeList.Add(2.0);

要么

A.SomeList.RemoveAt(0);

換句話說,什么時候鎖被釋放?

這里沒有線程安全。

lock在其保護的塊完成后立即釋放,就在屬性返回之前,因此對鎖定不會保護對Add ad RemoveAt的調用。

您在問題中顯示的鎖定沒有多大用處。

要使列表操作線程安全,您需要實現自己的Add / Remove / etc方法來包裝列表中的那些。

public void Add(double item)
{
    lock(_list)
    {
        _list.Add(item);
    }
}

此外,最好將列表本身隱藏在類的消費者中,即將字段設為私有。

退出lock語句的主體時會釋放lock 這意味着您的代碼不是線程安全的。

換句話說,您可以確定兩個線程不會執行return someList在同一對象上return someList 但是,當另一個線程執行RemoveAt() ,一個線程肯定可能會執行Add() RemoveAt() ,這使得它非線程安全。

當鎖內的代碼完成執行時,鎖被釋放。 此外,對此進行鎖定只會影響對象的當前實例

好吧,只是為了它的地獄。
通過使用已經線程安全的體系結構,有一種方法可以使對象線程安全。

例如,您可以使對象成為單個線程COM對象。 COM對象將是線程安全的,但您將支付性能(懶惰和不管理自己的鎖)的代價。

在C#中創建一個COM對象

......其他人已經說過,但只是為了使問題正式化......

  • 首先, lock (this) {...}建議一個'范圍' - 例如像using (){} - 它只鎖定(在這種情況下)這里的變量。 這實際上是一件“好事”:),好像你不能依賴它,整個鎖/同步概念將毫無用處,
  • lock (this) { return something; } lock (this) { return something; }是一種的一個矛盾-它返回的東西,解鎖它返回非常同一時刻,
  • 我認為的問題是理解它是如何工作的。 'lock()'在對象狀態下沒有'持久',所以你可以返回它等等。看看這里是如何實現鎖如何正常工作? - 答案解釋了它。 它更像是一個“關鍵部分” - 即你保護'代碼'的某些部分,它使用變量 - 而不是變量本身。 任何類型的同步都需要“同步對象”來保存鎖定 - 並且一旦不再需要鎖定就被處理掉。 看一下這篇文章https://stackoverflow.com/a/251668/417747,Esteban很好地制定了,

“最后,存在一種常見的誤解,即lock(this)實際上修改了作為參數傳遞的對象,並且在某種程度上使其成為只讀或不可訪問。這是錯誤的。作為參數傳遞給鎖定的對象僅用作關鍵“ (這是一個引用)

  • 你要么(通常)鎖定一個類方法,屬性的'私有代碼'... - 同步對你正在做的事情的訪問 - 並訪問私有成員(通常再次),以便其他人無法訪問它/ o瀏覽同步代碼。
  • 或者你創建一個線程安全的“結構” - 就像一個列表 - 它已經在內部“同步”,以便你可以以線程安全的方式訪問它。 但是沒有這樣的東西(或者沒有使用,幾乎從不)因為傳遞鎖定或者有一個地方鎖定變量,而代碼的另一部分解鎖它等等(在這種情況下,它是某種類型的EventWaitHandle ,相當習慣於在“遠程”代碼之間同步事物,其中一個在另一個代碼上觸發等等。)
  • 在你的情況下,我認為選擇'同步結構',即內部處理的列表,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM