gpt4 book ai didi

C# 锁和新手多线程问题

转载 作者:太空狗 更新时间:2023-10-29 20:34:33 26 4
gpt4 key购买 nike

关于 .NET 中多线程的一些新手问题,我认为这将有助于强化我正在尝试吸收的一些概念 - 我已经阅读了一些多线程 Material (包括 Albahari 电子书),但我觉得我只需要一些确认帮助插入这些概念的一些问题

  1. 锁范围保护代码的共享区域 - 假设有一个线程执行一个方法,该方法在循环中递增一个简单的整数变量 x - 然而这不会保护其他地方的代码,这些代码也可能会改变变量 x 例如在另一个线程的另一个方法中......

    由于这是两个不同的代码区域,可能会影响同一个变量,我们是否可以通过对变量 x 周围的两个锁定范围使用相同的锁定变量来锁定两个代码区域来解决这个问题?如果您使用不同的锁变量锁定两个代码区域,这将无法正确保护变量?

  2. 为了进一步说明这个例子,使用相同的锁变量,如果出于某种原因,一个方法中的代码进入某个无限循环并且从未放弃锁变量会发生什么 - 代码中的第二个区域怎么可能其他方法检测到这个?

  3. 锁变量的选择如何影响锁的行为?我已经阅读了很多关于这个主题的文章,但似乎永远找不到明确的答案——在某些情况下,人们明确地使用一个对象变量专门用于此目的,其他时候人们使用 lock(this) ,最后有几次我我见过人们使用类型对象。

    锁变量的不同选择如何影响锁的行为/范围,以及在哪些情况下使用一个锁变量更有意义?

  4. 假设你有一个哈希表封装在一个类中,暴露了添加、删除、获取和某种计算方法(比如每个对象代表一个数量,这个方法对每个值求和)并且所有这些方法都被锁定 - 然而,一旦引用该集合中的对象可供其他代码使用并传递给应用程序,该对象(不是哈希表)现在将超出该类方法周围的锁定范围..然后您如何保护对那些方法的访问/更新从哈希表中获取的实际对象,这可能会干扰计算方法?

感谢提供的任何有助于我强化这些概念的启发式方法 - 谢谢!

最佳答案

1) 是

2) 这是一个死锁

3) 您想要阻止的代码部分是您的类的实现细节。使用 lock(this)lock(this.GetType()) 公开锁定对象是自找麻烦,因为现在外部代码可以锁定同一个对象并阻止您的代码无意地或恶意地。锁对象应该是私有(private)的。

4) 你的意思不是很清楚,你当然不想直接公开哈希表。将其作为类的私有(private)字段,将其封装起来即可。

但是,随着您公开的公共(public)方法和属性的数量的增加,您可以使用线程安全地将您的类公开给客户端代码的可能性会迅速下降。您很快就会到达只有客户端代码才能正确获取锁的地步。当客户端代码持有属性值时,细粒度锁定为线程竞争创造了很多机会。假设您返回一个 Count 属性值。当它使用该值时,就像在 for 循环中一样,Count 属性可能已经改变。只有最仔细的设计才能避免这些陷阱,非常头疼。

此外,细粒度锁定效率非常低,因为它不可避免地在代码的最内部部分完成。锁并不那么昂贵,大约需要 100 个 CPU 周期,但它很快就会加起来。如果类对象实际上并未在多个线程中使用,则尤其浪费精力。

然后你别无选择,只能声明你的类线程不安全,客户端代码需要以线程安全的方式使用它。这也是许多 .NET 类不是线程安全的核心原因。这是线程很难正确执行的最大原因,最不可能正确执行线程的程序员负责完成最困难的事情。

关于C# 锁和新手多线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11925285/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com