好的,这就是我的财产
public List<String> names{
get{
lock(_names)
return _names;
}
set{
lock(_names)
_names = value
}
}
private List<String> _names;现在假设我对像这样的名字做了个foreach
foreach(String s in names)
{
Console.WriteLine(s);
}我的问题是,names是在整个foreach中锁定的,还是只在每次设置s时锁定lock,然后在foreach中解锁。
如果这让人困惑,假设我试着这样做
foreach(String s in names)
{
lock(names)
Console.WriteLine(s);
}我会陷入僵局吗?
发布于 2012-01-08 08:23:33
get_Names方法将只被调用一次,并且在项的迭代期间锁将结束(将会有no锁)。这可能不是您想要的,您可能应该使用更细粒度的锁,例如:
lock (someLockObject)
{
foreach(String s in names)
{
Console.WriteLine(s);
}
}当您在循环中锁定时,您将一个接一个地获取多个锁,这几乎肯定不是您想要的,因为操作foreach循环将不再是原子的。
发布于 2012-01-08 08:26:26
lock(_names) return _names;简写为:
try
{
Monitor.Enter(_names);
return _names;
}
finally
{
Monitor.Exit(_names);
}这相当于:
Monitor.Enter(_names);
Monitor.Exit(_names);
return _names;从这个角度来看,应该更清楚地表明锁是不必要的。您可能会对使用其中一个thread-safe collections感兴趣
发布于 2012-01-08 08:23:11
它不是锁在foreach里面的。它被锁定了一次,以get一个引用,然后迭代。(此外,属性内的lock语句目前是不必要的;这些操作是原子的。)
最有可能的情况是,您应该锁定循环体之外的位置,以及修改集合的位置。
对于您的编辑,请不要。这不是一个并行的foreach,所以循环不可能自己卡住,更不用说死锁了。再说一次,这只会浪费处理能力。
https://stackoverflow.com/questions/8774314
复制相似问题