这有什么区别:
internal class MyClass
{
private readonly object _syncRoot = new Object();
public void DoSomething()
{
lock(_syncRoot)
{
...
}
}
public void DoSomethingElse()
{
lock(_syncRoot)
{
...
}
}
}
和此:
internal class MyClass
{
[MethodImpl(MethodImplOptions.Synchronized)]
public void DoSomething()
{
...
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void DoSomethingElse()
{
...
}
}
我看到的唯一区别是第一种方法锁定某个私有成员,而第二种方法锁定实例本身(因此它应该锁定实例中的其他所有内容)。是否有任何使用方法的一般建议?我目前在项目中发现了两个具有相似目的的课程,每个课程都采用不同的方法编写。
编辑:
也许还有一个问题。是这样的:
internal class MyClass
{
[MethodImpl(MethodImplOptions.Synchronized)]
public void DoSomething()
{
...
}
}
完全相同:
internal class MyClass
{
public void DoSomething()
{
lock(this)
{
...
}
}
}
答案 0 :(得分:36)
首选方法是首选,因为您可以(并且应该)将_syncRoot设为私有。这降低了死锁的风险。
MethodImplOptions.Synchronized
是一个早先雄心勃勃的想法遗留下来的结果,毕竟结果并不那么好。
关于最后一个问题:是的,根据this blog,它们在功能上是等价的(但没有以相同的方式实施)。并且由于死锁情况,不鼓励所有形式的lock(this)
。{{1}}。
答案 1 :(得分:13)
结帐http://blogs.msdn.com/b/bclteam/archive/2004/01/20/60719.aspx和http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_20926988.html
他们讨论了lock(this)
并且不鼓励使用它,因为:
完全不相关的代码也可以选择锁定该对象
引自EE:
如果锁定对象,则需要访问此特定对象的所有其他线程将等待,直到另一个对象完成。但是,如果将方法标记为已同步,则不会在多个线程上执行此特定方法。 Lock保护对象,Synchronized保护方法。
答案 2 :(得分:8)
快速查看并发现便携式设备不支持MethodImplOptions.Synchronized。
还有一句话:
锁定实例或关于 类型,与Synchronized标志一样, 不建议公共类型, 因为你自己以外的代码都可以 锁定公共类型和 实例。这可能会导致死锁 或其他同步问题。
答案 3 :(得分:2)
我认为差异取决于装饰方法中引用的对象。从我读过的,装饰实际上在IL中实现了lock()。
最好的方法是根据需要进行最具体的锁定。
答案 4 :(得分:1)
本文可能会对您有所帮助:http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml
通常我会避免锁定'this',因为私有锁变量可以提供更好的控制。我建议锁定'this',如果它是一个自定义集合类,就像SyncRoot一样,如果这是必需的。
Hasanain