为什么锁定公共对象是一个坏主意

Chr*_*low 16 c# multithreading locking

好吧,我已经使用了很多锁,但我以前从未有过这种情况.我有两个不同的类,包含用于修改相同的MSAccess数据库的代码:

public class DatabaseNinja
{
    public void UseSQLKatana
    {
        //Code to execute queries against db.TableAwesome
    }
}

public class DatabasePirate
{
    public void UseSQLCutlass
    {
        //Code to execute queries against db.TableAwesome
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个问题,因为数据库的事务不能并行执行,并且这些方法(UseSQLKatana和UseSQLCutlass)由不同的线程调用.

在我的研究中,我发现使用公共对象作为锁定对象不好的做法,那么如何锁定这些方法以使它们不会串联运行?答案只是将这些方法放在同一个类中吗?(在我的真实代码中,这实际上并不那么简单)

Eri*_*ert 16

好吧,首先,您可以创建第三个类:

internal class ImplementationDetail
{
    private static readonly object lockme = new object();
    public static void DoDatabaseQuery(whatever)
    {
        lock(lockme)
             ReallyDoQuery(whatever);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在UseSQLKatana和UseSQLCutlass调用ImplementationDetail.DoDatabaseQuery.

其次,您可以决定不担心它,并锁定两种类型都可见的对象.避免这种情况的主要原因是因为很难推断谁正在锁定对象,并且难以防止恶意部分信任的恶意代码锁定对象.如果您不关心任何一个缺点,那么您不必盲目遵循指南.


Dan*_*Man 8

锁定公共对象的不良做法是,您永远无法确定ELSE是谁锁定该对象.虽然不太可能,但有一天其他人可以决定他们想要获取你的锁对象,并做一些最终调用你的代码的进程,你锁定到同一个锁对象,现在你有一个不可能的死锁来搞清楚.(使用'this'也是同样的问题).

更好的方法是使用公共Mutex对象.这些更重要,但调试问题要容易得多.

  • 这个答案也是对这一点的一个很好的解释:http://stackoverflow.com/questions/1873201/why-are-locks-performed-on-separate-objects (2认同)