【发布时间】:2013-06-11 06:42:26
【问题描述】:
我想实现一个线程安全列表,但必须确保整个操作块的线程安全,而不仅仅是单个操作(例如添加、删除等)。用例应如下所示:
list.Lock();
list.Add(sth);
list.RemoveAt(4);
list.Unlock();
我希望列表对任何操作都需要锁定。例如:
list.Add(sth);
在没有事先锁定的情况下调用应该会导致异常。这就是为什么我不使用 lock() 语句的原因 - 锁定检查对于此解决方案至关重要。
使用 Monitor 实现这样的列表并不难 - 但只有在想要检查列表是否被锁定之前。我想到了以下场景:
// Inside list class
private object lockObject;
private bool locked;
public void Lock()
{
Monitor.Enter(lockObject);
locked = true;
}
public void Unlock()
{
Monitor.Exit(lockObject);
locked = false;
}
不幸的是,此代码容易出现竞争条件 - 无论 locked 是在进入或离开临界区之前还是之后设置。
另一种方法是使用TryEnter,但是这种方法实际上是在没有获得锁的情况下进入了临界区,这也可能导致竞争条件。
我应该如何实现这个机制以保证线程安全以及如何在检查列表是否被锁定时避免竞争条件?
【问题讨论】:
-
暂且不说我提出的解决方案,我想说您的实现问题可以通过使用 compareAndSet 来解决(我不确定它在 C# 世界中是如何调用的)
-
作为旁注,这些有帮助吗? Thread-Safe Collections
标签: c# list concurrency thread-safety