我需要在我们的框架中实现应该执行锁定机制的类。
我们有几个线程,它们的编号为 0,1,2,3...。我们有一个名为 ResourceHandler
的静态类,它应该将这些线程锁定在给定的对象上。要求是 n Lock()
调用应由 m Release()
调用释放,其中 n = [0..] 且 m = [0..]。因此,无论对单个对象执行多少次锁定,只需一次 Release()
调用就足以解锁所有对象。更进一步,如果对象没有被锁定,Release()
调用不应该执行任何操作。我们还需要知道哪些对象被锁定在哪些线程上。
我有这个实现:
public class ResourceHandler
{
private readonly Dictionary<int, List<object>> _locks = new Dictionary<int, List<object>>();
public static ResourceHandler Instance {/* Singleton */}
public virtual void Lock(int threadNumber, object obj)
{
Monitor.Enter(obj);
if (!_locks.ContainsKey(threadNumber)) {_locks.Add(new List<object>());}
_locks[threadNumber].Add(obj);
}
public virtual void Release(int threadNumber, object obj)
{
// Check whether we have threadN in _lock and skip if not
var count = _locks[threadNumber].Count(x => x == obj);
_locks[threadNumber].RemoveAll(x => x == obj);
for (int i=0; i<count; i++)
{
Monitor.Exit(obj);
}
}
// .....
}
其实我这里担心的是线程安全。我实际上不确定它是否是线程安全的,解决这个问题真的很痛苦。我是否正确执行任务以及如何确保这是线程安全的?
最佳答案
您的Lock
方法锁定目标对象
,但_locks
字典可以由任何线程随时访问。您可能需要添加一个私有(private)锁对象来访问字典(在 Lock
和 Release
方法中)。
还请记住,通过使用这样的 ResourceHandler,其余代码(使用线程)有责任释放所有已使用的对象(例如常规的 lock ()
block )这个问题是因为每当您离开锁
的范围时,该对象就会被释放)。
在计算对象被锁定的次数时,您可能还需要使用 ReferenceEquals
,而不是 ==
。
关于c# - 多重锁定任务(线程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11325653/