使用现有对象而不是创建特定锁对象是否安全?

时间:2011-11-21 08:46:34

标签: c# multithreading locking thread-safety

编辑:事实证明,当我浏览时,我发现了一个与我之前没有找到的问题相同的问题:Difference between lock(locker) and lock(variable_which_I_am_using)

我正在查看一些代码并尝试解决锁定问题,我想到了。

现在我注意到在一些代码中我正在审查一个对象是这样创建的:

private HashSet<Graphic> clustersInUse = new HashSet<Graphic>();

然后在代码中进一步使用如下:

lock (clustersInUse)
{
   // Do something with the Hashset
}

现在,这样做是否存在问题,而不是为锁创建特定对象。像这样:

private object clusterLocker = new object();

如果上面的clustersInUse以某种方式被置于公共财产中,会发生什么呢?

此外,如果某些东西试图访问clustersInUse而没有锁定它,而它被锁定在另一个线程中会发生什么呢?

2 个答案:

答案 0 :(得分:3)

一般规则是您希望控制锁定对象的范围,以防止某些未知代码导致意外行为。在这种情况下,您正在使用私有实例变量,因此只要您没有分发对它的引用,您就可以了。

如果您正在分发引用并锁定它,而其他代码正在锁定这些引用(例如,在修改集合时),更改行为可能会轻易引入线程错误。

如果某人将其置于公共财产中,如果他们锁定了该公共财产并将其作为“分发参考”,那么您对锁定的调用将会阻止,直到他们将其解锁为止。这是否可取取决于他们对收藏品的处理方式。

锁定对象对于将对象用于除同步之外的任何其他目的没有任何影响。

答案 1 :(得分:2)

你已经回答了自己的问题。对于锁定,通常最好是专门为此目的创建一个对象,并且通常私有地保存以供高级别表示同步逻辑的访问器方法使用。