更好的是:
锁定语句中有大的代码区域
或
在大面积有小锁?..
此示例中的交换不可更改。
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));
}
.....
答案 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。