C# 相同对象性能的嵌套锁
对同一对象使用嵌套锁是否会造成性能损失 假设我们有:C# 相同对象性能的嵌套锁,c#,concurrency,C#,Concurrency,对同一对象使用嵌套锁是否会造成性能损失 假设我们有: public void AddRange(IEnumeratable<Item> items) { lock (_syncObject) { foreach (Item item in items) { InsertItem(item); } } }
public void AddRange(IEnumeratable<Item> items)
{
lock (_syncObject)
{
foreach (Item item in items)
{
InsertItem(item);
}
}
}
public void InsertItem(Item item)
{
lock (_syncObject)
{
//..
}
}
public void AddRange(IEnumeratable项)
{
锁定(_syncObject)
{
foreach(项目中的项目)
{
插入项(项目);
}
}
}
公共无效插入项(项)
{
锁定(_syncObject)
{
//..
}
}
在“性能方面”这样做可以吗
提前感谢。
锁
不是免费的。它必须在返回之前检查某些东西。有多少事情以及它必须做什么,取决于实施情况。我猜这种用法很常见,MS为此用例做了一些优化
我仍然建议您使用一个单独的AddRange实现,一次完成所有事情。这当然取决于类接口的其余部分(是否有侦听器,以及它们是否可以接收添加了多个对象的消息等)
这是一个相当简单的测试用例,执行数百万个嵌套锁定(如您所建议的),并对其他锁执行相同的操作
另请注意,如果使用非嵌套锁,则可能会在要添加的范围中间获得一个对象:
AddRange _sync1
AddItem _sync2
AddItem _sync2
--- interruption, other thread calls:
AddItem _sync2
--- AddRange again:
AddItem _sync2
当与单个_syncObject同步时,没有人可以中断,因为锁已由另一个线程持有。我不知道性能如何受到影响,但当我们预计它会降低性能时,我建议您以另一种方式实现代码:
public void InsertItem(Item item)
{
AddRange(new IEnumeratable({item}))
}
public void AddRange(IEnumeratable<Item> items)
{
lock (_syncObject)
{
foreach (Item item in items)
{
// Insert code ..
}
}
}
public void插入项(项)
{
AddRange(新的IEnumeratable({item}))
}
公共无效添加范围(IEnumeratable项)
{
锁定(_syncObject)
{
foreach(项目中的项目)
{
//插入代码。。
}
}
}
@AddRange(新的IEnumeratable({item})):
我不是语法wizkid,所以如果这不正确,请纠正我 锁是有代价的,我建议您实现如下代码:
public void AddRange(IEnumeratable<Item> items)
{
lock (_syncObject) // Locking only once.
{
foreach (Item item in items)
{
InsertItemImpl(item);
}
}
}
private void InsertItemImpl(Item item)
{
// inserting the item
}
public void InsertItem(Item item)
{
lock (_syncObject)
{
InsertItemImpl(item);
}
}
public void AddRange(IEnumeratable项)
{
lock(\u syncObject)//只锁定一次。
{
foreach(项目中的项目)
{
InsertItemImpl(项目);
}
}
}
私有void InsertItemImpl(项)
{
//插入项目
}
公共无效插入项(项)
{
锁定(_syncObject)
{
InsertItemImpl(项目);
}
}
我认为最好将Insert实现转移到另一个方法,而不是为每个添加项创建新集合。