c# - 多线程,通用锁

标签 c# multithreading locking

我有一个看起来很像这样的单例类,

public class CfgHandler
{
    private static readonly string ConfigDir = "Config";

    public T Get<T>() where T : class, new()
    {
        string cfgFile = Path.Combine(ConfigDir, typeof(T).FullName + ".json");

        if (File.Exists(cfgFile))
        {
            var reader = new JsonReader();
            return reader.Read<T>(File.ReadAllText(cfgFile));
        }

        return null;
    }

    public void Set<T>(T instance) where T : class, new()
    {
        string cfgFile = Path.Combine(ConfigDir, typeof(T).FullName + ".json");

        var writer = new JsonWriter();
        string json = writer.Write(instance);

        File.WriteAllText(cfgFile, json);
    }
}

类在多线程环境下使用,想加锁。但不是整个类(class)的一个锁,因为我不想要 cfg.Set<Foo>(); 之间的竞争条件。和 cfg.Set<Bar>()因为他们处理不同的数据。

我考虑过将以下类添加到 CfgHandler ,

private static class Locks<T>
{
    private static object _lock = new object();
    public static object Lock { get { return _lock; } }
}

然后像这样锁定(Get和Set),

public void Set<T>(T instance) where T : class, new()
{
    lock(Locks<T>.Lock)
    {
        // save to disk
    }
}

我是否漏掉了一些微不足道的东西?有没有更好的方法来实现我的目标?

最佳答案

按实例锁定还是按类型锁定?

你这样做的方式(使用静态 Locks<T>.Lock )意味着每次调用 Set<Foo>即使在不同的 CfgHandler 实例上,也会共享相同的锁。那是你要的吗?我猜你最好只锁定每个实例 - 它会为你节省 Locks<T> 的复杂性.只需声明一个私有(private)实例成员 ( private object _lock = new object(); ) 并使用它 ( lock(this._lock) )

编辑 如果您使用的是 CfgHandler 的单例实例并想按类型锁定,那么我想你的方法非常好。如果您不使用单个实例,但仍想按类型锁定,那么只需确保使用 Locks<T> 的实例即可。而不是将其设为静态。

关于c# - 多线程,通用锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10334394/

相关文章:

c# 在循环/迭代长过程时性能下降

c - 使用 GDB 单步调试多线程应用程序

java - 如何停止当前线程直到其他线程完成执行?

c# - 将 double 值转换为二进制值

c# - 无法删除 Microsoft.Bcl.Build.Tasks.dll

sql - 如何停止 Sql Server 的用户实例? (Sql Express 用户实例数据库文件被锁定,即使在停止 Sql Express 服务后)

java - 使用 Apache ZooKeeper 实现死锁检测

locking - 无法在锁或事务内启动/停止缓存

c# - C# 中的 FileReader 类

c++ - 我需要在Boost线程函数中调用unlock()吗?