锁定代码区域的正确方法是什么

时间:2011-12-27 13:37:40

标签: c# multithreading locking

更好的是:
锁定语句中有大的代码区域

在大面积有小锁?.. 此示例中的交换不可更改。

lock (padLock)
{
  foreach (string ex in exchanges)
  {
     sub.Add(x.ID, new Subscription(ch, queue.QueueName, true));
.........
}

foreach (string ex in exchanges)
{
  lock (padLock) 
  {
     sub.Add(x.ID, new Subscription(ch, queue.QueueName, true));
  }
.....

5 个答案:

答案 0 :(得分:1)

良好的做法是在给定时间仅锁定您希望仅由一个线程执行的区域

如果该区域是整个foreach循环,则第一种方法很好

但如果你所展示的那个区域只是一行,那么我采用第二种方法

答案 1 :(得分:1)

更广泛的锁定 - 您从多线程获得的越少,反之亦然 因此,锁的使用完全取决于逻辑。仅锁定更改且必须一次只能由一个线程运行的事物和地点

如果锁定使用集合sub - 使用较小的锁定,但如果同时并行运行多个foreach循环

答案 2 :(得分:1)

在这种特殊情况下,最好的选择是第一个,因为否则你只是浪费时间锁定/解锁,因为你必须执行整个循环。因此,无论如何在循环中并行执行单独的原子操作的机会并不多。

有关关键部分尺寸的更多一般性建议,请查看以下文章:http://software.intel.com/en-us/articles/managing-lock-contention-large-and-small-critical-sections/

答案 3 :(得分:1)

我认为有两个不同的问题:
1.哪个是正确的?
2.哪种表现更好?

正确性问题很复杂。这取决于您的数据结构,以及您打算如何保护它们。如果“sub”对象不是线程安全的,那么你肯定需要大锁。

性能问题更简单,更不重要(但出于某种原因,我认为你更关注它)。
许多小锁可能会更慢,因为它们只是做更多的工作。但是如果你设法在没有锁定的情况下运行大部分循环代码,你会得到一些并发性,所以它会更好。

答案 4 :(得分:0)

您无法使用给定的代码段有效判断哪个是“正确的”。第一个例子说,人们只能看到来自交易所的部分内容的sub是不行的。第二个例子说,人们可以看到只包含来自交换的部分内容的sub。