【问题标题】:using ConcurrentStack使用并发堆栈
【发布时间】:2011-04-29 09:12:00
【问题描述】:

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

【问题讨论】:

  • 您是否尝试搜索 .NET4 并发堆栈?例如codethinked.com/post/2010/02/01/…
  • 1.创建一个ConcurrentStack 实例。 2.创建多个线程。 3. 从 ConcurrentStack 实例上的任意线程调用 Push 方法。您在哪一部分需要帮助?
  • @Hightechrider,我进行了搜索,但我没有找到任何满足我需要的东西作为一个很好的例子。但是感谢您的链接!
  • @dtb - 可能只是安慰。对于许多开发人员来说,多线程仍然超出范围或新奇。
  • @dtb,这就是我需要知道的!不确定我是否需要锁定任何东西,但我确实读过它是线程安全的。但我找不到适合我需要的好例子。

标签: c# multithreading stack


【解决方案1】:

线程使用:

_stack.Push(obj);

在另一个线程上使用:

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

我推荐阅读this MSDN blog post

【讨论】:

    【解决方案2】:

    到目前为止,您已经收到了一些不错的答案。让我提供一些有关其设计的有用信息,以帮助您更好地了解如何使用它。请注意,没有 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 的原因。也许在将来的版本中将提供给我们。

    【讨论】:

    • 对于最后一个示例,要创建线程安全的最大大小,有适用于 .NET 4.0 和更高版本的 BlockingCollection 类。
    【解决方案3】:

    从多个线程向ConcurrentStack 添加值相当简单。只需引用可用的堆栈并从需要添加数据的任何线程调用Push。这里不需要特殊的锁定,因为集合旨在以这种方式从多个线程中使用。

    【讨论】:

      【解决方案4】:

      您创建您的ConcurrentStack&lt;string&gt;,并确保所有线程都引用它。

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

      theStack.Push("foo");
      

      【讨论】:

        【解决方案5】:

        恭喜,您为多线程使用选择了正确的容器。整个类都是线程安全的,建议用于您的场景,因此请酌情使用PushPushRange

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

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-06
        • 2017-02-02
        • 2012-04-27
        • 2020-11-17
        • 1970-01-01
        • 1970-01-01
        • 2017-07-26
        • 1970-01-01
        相关资源
        最近更新 更多