【问题标题】:How to iterate on concurrentLinkedQueue by multiple threads?如何通过多个线程迭代concurrentLinkedQueue?
【发布时间】:2017-07-24 22:20:10
【问题描述】:

在我的应用程序中,数据生成速度(存储在 concurrentLinkedQueue 中)大于我可以使用单线程消耗的速度。

我决定从创建 4 个线程来使用数据开始,以防止我的应用程序出现“内存不足异常”。

问题:

  • 对于上述问题还有其他更好的设计示例吗?
  • 我们可以用多个线程迭代 concurrentLinkedQueue 并在迭代时删除元素吗?

内存一致性效果:与其他并发集合一样, 在将对象放入 ConcurrentLinkedQueue 发生在访问之后的操作之前 或从另一个 ConcurrentLinkedQueue 中删除该元素 线程。

【问题讨论】:

  • 我会看blocking queues,因为您的消费者线程可能不得不处理当他们“超过”生产者时的情况。然后您可以通过向线程发送一些特殊项目来停止线程(4 个副本,因此每个线程将消耗一个)
  • @tevemadar 感谢您的建议 :)

标签: java multithreading concurrency


【解决方案1】:

我认为你不应该迭代,而是创建 4 个线程,每个线程从队列中轮询数据,这样轮询的数据将被删除或换句话说被消耗

// your queue
ConcurrentLinkedQueue concurrentLinkedQueue = new ConcurrentLinkedQueue();

    // create 4 Threads
    for (int i = 0; i < 4; i++) {
        new Thread(() -> {
            while (!concurrentLinkedQueue.isEmpty()) {
                // consume element
                var element = concurrentLinkedQueue.poll();

                // do something with element
                // here
            }
        }).start();
    }

【讨论】:

  • 为什么不while (!concurrentLinkedQueue.isEmpty())
  • @LeiYang,很好的建议。一个更好
【解决方案2】:

您应该在ConcurrentLinkedQueue 上使用offerpoll 方法,而不是直接使用迭代器。迭代器是weakly consistent

while(true) {
  final Item item = queue.poll();
  if (item == null) {
    break;
  }
  // do something with item
}

多个线程同时调用offer 和/或poll 是安全的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多