C# 我能摆脱这个读锁吗?
我有以下助手类(简化): (在C# 我能摆脱这个读锁吗?,c#,.net,.net-2.0,locking,C#,.net,.net 2.0,Locking,我有以下助手类(简化): (在查找方法中删除了锁(_syncRoot))。问题是这会使用不必要的内存量(这可能不是问题),我可能会使\u查找不稳定,但我不确定该如何应用。() 使用ReaderWriterLock。我相信这会让事情变得更糟,因为被锁定的地区很小 欢迎提出建议 更新: 缓存的值是不可变的。目前正在工作,所以没有什么优雅的东西,我们提出了这个(未经测试) 公共静态类缓存 { 私有静态只读对象_syncRoot=新对象(); 私有静态字典_lookup=新字典(); 公共静态类OneT
查找
方法中删除了锁(_syncRoot)
)。问题是这会使用不必要的内存量(这可能不是问题),我可能会使\u查找
不稳定,但我不确定该如何应用。()
ReaderWriterLock
。我相信这会让事情变得更糟,因为被锁定的地区很小缓存的值是不可变的。目前正在工作,所以没有什么优雅的东西,我们提出了这个(未经测试)
公共静态类缓存
{
私有静态只读对象_syncRoot=新对象();
私有静态字典_lookup=新字典();
公共静态类OneToManyLocker
{
私有静态只读对象WriteLocker=新对象();
私有静态只读列表ReadLockers=new List();
私有静态只读对象myLocker=new Object();
公共静态对象GetLock(LockType LockType)
{
锁(写器)
{
if(lockType==lockType.Read)
{
var newReadLocker=新对象();
锁(myLocker)
{
ReadLockers.Add(newReadLocker);
}
返回newReadLocker;
}
foreach(读卡器中的var读卡器)
{
锁(readLocker){}
}
返回写器;
}
}
公共枚举锁类型{Read,Write};
}
公共静态void Add(类型、字符串值)
{
lock(OneToManyLocker.GetLock(OneToManyLocker.LockType.Write))
{
_添加(类型、值);
}
}
公共静态字符串查找(类型)
{
字符串结果;
锁(OneToManyLocker.GetLock(OneToManyLocker.LockType.Read))
{
_lookup.TryGetValue(类型,输出结果);
}
返回结果;
}
}
您将需要对读储物柜进行某种清理,但应该是线程安全的,允许一次多次读取,同时也锁定写入,除非我目前在工作中完全遗漏了一些东西,所以没有什么优雅的东西,我想到了这个(未经测试)
公共静态类缓存
{
私有静态只读对象_syncRoot=新对象();
私有静态字典_lookup=新字典();
公共静态类OneToManyLocker
{
私有静态只读对象WriteLocker=新对象();
私有静态只读列表ReadLockers=new List();
私有静态只读对象myLocker=new Object();
公共静态对象GetLock(LockType LockType)
{
锁(写器)
{
if(lockType==lockType.Read)
{
var newReadLocker=新对象();
锁(myLocker)
{
ReadLockers.Add(newReadLocker);
}
返回newReadLocker;
}
foreach(读卡器中的var读卡器)
{
锁(readLocker){}
}
返回写器;
}
}
公共枚举锁类型{Read,Write};
}
公共静态void Add(类型、字符串值)
{
lock(OneToManyLocker.GetLock(OneToManyLocker.LockType.Write))
{
_添加(类型、值);
}
}
公共静态字符串查找(类型)
{
字符串结果;
锁(OneToManyLocker.GetLock(OneToManyLocker.LockType.Read))
{
_lookup.TryGetValue(类型,输出结果);
}
返回结果;
}
}
您需要对读储物柜进行某种清理,但应该是线程安全的,允许一次进行多个读操作,同时也锁定写操作,除非我完全缺少一些东西来完全移除锁(与“无锁”略有不同)当锁几乎被消除,剩下的被巧妙地替换为互锁指令时),您需要确保您的字典是不可变的。如果字典中的项不是不可变的(因此它们有自己的锁),您可能不应该担心字典级别的锁
如果您可以使用新的4.0集合-ConcurrentDictionary那里符合您的标准(请参阅和)。要完全删除锁(与“无锁”稍有不同,在“无锁”中,锁几乎被消除,剩余的被巧妙地替换为互锁指令),您需要确保字典是不可变的。如果字典中的项不是不可变的(因此它们有自己的锁),您可能不应该担心字典级别的锁
- 不要使用普通锁,如果查找速度快(字典不快),则使用自旋锁
- 如果情况并非如此,则使用。这允许多个读卡器和一个写卡器
- 不要使用普通锁,如果查找失败,请转到spinlock
public static class Cache { private static readonly object _syncRoot = new object(); private static Dictionary<Type, string> _lookup = new Dictionary<Type, string>(); public static void Add(Type type, string value) { lock (_syncRoot) { _lookup.Add(type, value); } } public static string Lookup(Type type) { string result; lock (_syncRoot) { _lookup.TryGetValue(type, out result); } return result; } }
public static void Add(Type type, string value) { lock (_syncRoot) { var lookup = new Dictionary<Type, string>(_lookup); lookup.Add(type, value); _lookup = lookup; } }
public static class Cache { private static readonly object _syncRoot = new object(); private static Dictionary<Type, string> _lookup = new Dictionary<Type, string>(); public static class OneToManyLocker { private static readonly Object WriteLocker = new Object(); private static readonly List<Object> ReadLockers = new List<Object>(); private static readonly Object myLocker = new Object(); public static Object GetLock(LockType lockType) { lock(WriteLocker) { if(lockType == LockType.Read) { var newReadLocker = new Object(); lock(myLocker) { ReadLockers.Add(newReadLocker); } return newReadLocker; } foreach(var readLocker in ReadLockers) { lock(readLocker) { } } return WriteLocker; } } public enum LockType {Read, Write}; } public static void Add(Type type, string value) { lock(OneToManyLocker.GetLock(OneToManyLocker.LockType.Write)) { _lookup.Add(type, value); } } public static string Lookup(Type type) { string result; lock (OneToManyLocker.GetLock(OneToManyLocker.LockType.Read)) { _lookup.TryGetValue(type, out result); } return result; } }