C#锁和新手多线程问题

blu*_*utt 7 c# multithreading

关于.NET中的多线程的一些新手问题,我认为这将有助于强化我想要吸收的一些概念 - 我已经阅读了几种多线程材料(包括Albahari电子书),但我觉得我只需要对一些问题进行一些确认帮助推动这些概念回家

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

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

  2. 为了进一步说明这个例子,使用相同的锁变量,如果由于某种原因,一个方法中的代码进入某个无限循环并且永远不会放弃锁变量会发生什么 - 另一个方法中的第二个代码区如何检测到这个?

  3. 锁变量的选择如何影响锁的行为?我已经阅读了很多关于这个主题的帖子,但似乎永远无法找到明确的答案 - 在某些情况下,人们明确地使用了一个专门用于此目的的对象变量,其他时候人们使用锁定(这个),最后有时候我已经看到人们使用类型对象.

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

  4. 假设你有一个包含在类中的哈希表,暴露了add,remove,get和某种Calculate方法(比如每个对象代表一个数量,这个方法对每个值求和),所有这些方法都被锁定 - 但是,一旦引用了一个对象在该集合可用于其他代码并传递给应用程序时,此对象(不是散列表)现在将位于该类方法的锁定范围之外.那么您可以保护对这些实际对象的访问/更新从散列表,这可能会干扰Calculate方法?

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

Sci*_*ion 1

1)你是对的。您必须使用相同的锁对象来保护两个不同的代码区域,例如递增变量 x。

2) 这称为死锁,是多线程编程的难点之一。有一些算法可用于防止死锁,例如银行家算法。

3)有些语言使锁定变得容易,例如在.Net中,您只需创建一个对象并将其用作共享锁。这对于在给定进程内同步代码很有好处。Lock(this) 只是将锁应用于相关对象。但是,请尽量避免这种情况,而是创建一个私有对象并使用它。Lock(this) 可能会导致死锁情况。下面的锁对象可能只是关键部分的包装。如果您想跨不同进程保护资源,则需要一个更重的互斥锁,这需要锁定内核对象并且成本高昂,因此除非必须,否则不要使用。

4)您需要确保那里也应用了锁定。但可以肯定的是,当人们调用此引用上的方法时,他们调用的是采用同步的方法。