繁体   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