从 ConcurrentLinkedQueue 迭代和删除元素

Iterating and removing elements from ConcurrentLinkedQueue

我定义了一个 ConcurrentLinkedQueue 并像这样循环它:

 ConcurrentLinkedQueue clq 
 .forEach((carTask -> {
        

现在,如果我从队列中删除 carTask。这是一个元素
在我们执行 forEach 时在队列中会导致任何问题吗?

我想到的一个替代方案是将要删除的元素放入
在一个单独的列表中,一旦 forEach 结束,只需删除所有
列表中队列中的元素。
我不确定这种替代方法是否完美
有什么建议或更好的方法来解决这个问题吗?

此特定示例不会导致错误,因为 Queue 的此实现允许并发修改。

但是 通过 remove 方法从 Java 集合中删除元素,当您遍历元素时,通常会导致 ConcurrentModificationException。相反,使用 Iterator 并调用其 remove 方法是一个好习惯:

Collection<String> c = new LinkedList<>();
c.add("foo");
c.add("bar");
for(Iterator<String> it = c.iterator(); it.hasNext(); ) {
  String s = it.next();
  if(s.equals("foo")) {
    it.remove();
  }
}
// collection now contains only "bar"

除了防止ConcurrentModificationException,这是更可取的,因为remove对于很多集合的时间复杂度是线性。由于这个队列是作为链表实现的,所以必须遍历链表,直到找到要移除的元素。使用 Iterator,您已经找到了该元素,并且可以将其“就地”移除。

如果找到要删除的元素,并且它是队列中的最后一个元素怎么办?对该项目调用 remove 需要一直遍历到队列的末尾 再次 。此外,它需要为前面的每个元素调用 equals。您绝对不想将要删除的项目放入列表中,因为您将具有相同的负面性能特征(以及另一个 List 的分配)。