gpt4 book ai didi

c# - 如何实现线程安全列表?

转载 作者:太空狗 更新时间:2023-10-30 00:32:34 25 4
gpt4 key购买 nike

我想实现一个线程安全列表,但是必须确保整个操作 block 的线程安全,而不仅仅是单个操作(例如添加、删除等)。用例应如下所示:

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,但是如果没有获取到锁,这个方法实际上进入了临界区,这也可能导致竞争条件。

我应该如何实现这种线程安全的机制,以及如何在检查列表是否被锁定时避免竞争条件?

最佳答案

您可以让您的类负责锁定,并且只公开一个接受消费者指定的Action 的方法:

public class LockedCollection
{
private class CollectionImpl : ICollection<int>
{
//Collection methods
}

private sealed class CollectionWrapper : ICollection<int>, IDisposable
{
public CollectionWrapper(CollectionImpl inner)
{
_inner = inner;
}
private CollectionImpl _inner
//Collection methods all just wrapping calls to inner
public void Dispose()
{
_inner = null;
}
}


private CollectionImpl _instance - new CollectionImpl();
private object _lock = new object();

public void DoStuff(Action<ICollection<int>> task)
{
lock(_lock)
{
using(var wrapper = new CollectionWrapper(_instance))
{
task(wrapper);
}
}
}
}

消费者可以在 task 中进行他们喜欢的任何操作序列,并且您知道锁已被占用 - 因为您自己已占用。

关于c# - 如何实现线程安全列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17037965/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com