使用ConcurrentStack

时间:2010-10-22 20:38:32

标签: c# multithreading stack

我需要使用堆栈数据结构来保存字符串。但是这个堆栈将从多个线程访问。所以我的问题是,如何使用ConcurrentStack从多个线程添加数据?

5 个答案:

答案 0 :(得分:9)

恭喜,您已选择正确的容器进行多线程使用。整个班级都是线程安全的,并建议您的方案使用,因此请尽量使用PushPushRange

范围示例代码here使用并行化来演示多线程操作。

答案 1 :(得分:8)

到目前为止,您已收到一些相当不错的答案。让我提供一些有关其设计的有用信息,以帮助您更好地了解如何使用它。请注意,没有Pop方法。这是因为设计人员希望阻止您执行以下不安全的操作序列。它是不安全的,因为对Count属性和假设Pop方法的调用序列不是原子的,尽管集合被称为线程安全的。

while (stack.Count > 0)
{
  stack.Pop();
}

为了协调这个常见用例,设计人员使用了TryPop方法。这基本上允许您重写上面的内容,如下所示。这次代码是安全的。

object item;
while (stack.TryPop(out item))
{
  // Do something with the item here.
}

我的第一个例子的推论也存在于Push方法中。以下代码(这次合法)也不安全。

if (stack.Count < MAX_ITEMS)
{
  stack.Push(...);
}

后面的示例并不像前者那样常见,这可能是设计人员没有添加CAS - 类似等效操作TryPush的原因。也许在将来发布的版本中,我们可以使用。

答案 2 :(得分:1)

您创建了ConcurrentStack<string>,并确保所有线程都有对它的引用。

然后线程会调用Push来添加字符串:

theStack.Push("foo");

答案 3 :(得分:1)

从多个线程向ConcurrentStack添加值非常简单。只需引用可用的堆栈,然后从需要添加数据的线程中调用Push。此处不需要特殊锁定,因为该集合旨在以这种方式从多个线程中使用。

答案 4 :(得分:1)

一个线程使用:

_stack.Push(obj);

在另一个帖子上使用:

MyObj obj;    
if (_stack.TryPop(out obj))
    UseObj(obj);

我建议阅读this MSDN blog post