手动锁定和同步方法之间的区别

本文关键字:之间 区别 同步方法 锁定 | 更新日期: 2023-09-27 17:57:40

这两者之间有什么区别吗:

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) 
        {
            ...
        }
    }
}

手动锁定和同步方法之间的区别

首选第一种方法,因为您可以(也应该)使_syncRoot私有。这降低了死锁的风险。

MethodImplOptions.Synchronized是早期雄心勃勃的想法遗留下来的,但最终并不那么好。

关于最后一个问题:是的,根据这个博客,它们在功能上是等效的(但实现方式不同)。所有形式的lock(this)都不受欢迎,同样是因为死锁场景。

签出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:

如果锁定一个对象,则需要访问THIS SPECIFY object的所有其他线程都将等待,直到其他对象完成为止。但是,如果将方法标记为"已同步",则不会在多个线程上执行THIS SPECIFY method。Lock保护对象,Synchronized保护方法。

快速查看后发现便携式设备不支持MethodImplOptions.Synchronized.

还有一句话:

锁定实例或与Synchronized标志一样,不推荐用于公共类型,因为除了你自己的代码锁定公共类型,并实例。这可能会导致死锁或其他同步问题。

来源:http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions%28v=VS.100%29.aspx

我认为区别将取决于修饰方法中引用的对象。根据我所读到的,装饰实际上在IL.中实现了lock()

最好的方法是根据需要进行最具体的锁定。

本文可能会帮助您:http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml

一般来说,我会避免锁定"this",因为私有锁定变量可以提供更好的控制。我建议锁定"this",如果它是一个自定义集合类,或者类似SyncRoot的东西,如果这是必需的。

Hasanain