Java ConcurrentLinkedQueue上的迭代器不会迭代到下一个值

Java ConcurrentLinkedQueue上的迭代器不会迭代到下一个值,java,data-structures,concurrency,queue,java.util.concurrent,Java,Data Structures,Concurrency,Queue,Java.util.concurrent,我正在更新ConcurrentLinkedQueue,同时对其进行迭代。理论上,该队列上的迭代器在到达队列末尾之前不应停止。然而,在我下面给出的程序中,迭代器在迭代初始状态后停止,而不更新队列。我应该怎样克服这个问题 public static void printTree(Node root) { Queue<Node>q=new ConcurrentLinkedQueue<Node>(); q.add(root); Iterator<N

我正在更新ConcurrentLinkedQueue,同时对其进行迭代。理论上,该队列上的迭代器在到达队列末尾之前不应停止。然而,在我下面给出的程序中,迭代器在迭代初始状态后停止,而不更新队列。我应该怎样克服这个问题

public static void printTree(Node root) {
    Queue<Node>q=new ConcurrentLinkedQueue<Node>();
    q.add(root);

    Iterator<Node> iter = q.iterator();
    while(iter.hasNext()) {
        List<Node> childs = iter.next().getChildren();
        for(Node child:childs) {
            q.add(child);
        }
    }

    for (Node item:q) {
        System.out.println(item.getValue());
    }
}
它的输出是根的值传递给函数的值及其子函数的值。它应该显示儿童的价值观,但它不是。迭代器iter似乎只对第一次添加到队列中的根进行迭代,而不是更多。

在javadoc中:

返回的迭代器。。。保证在元素运行时遍历它们 在构造迭代器时存在,可以但不是 保证反映施工后的任何修改

本质上,当您创建迭代器时,它将提供队列创建时的视图。这是此集合是线程安全的原因之一:更改队列将并行进行,即不影响现有迭代器

在这种情况下,不需要使用线程安全集合。您可以使用支持ListIterator的列表。ListIterator是一个更强大的迭代器,它支持添加元素:

List<Node>q=new LinkedList<Node>();
q.add(root);

ListIterator<Node> iter = q.iterator();
while(iter.hasNext()) {
    List<Node> childs = iter.next().getChildren();
    for(Node child:childs) {
        iter.add(child);
    }
}

for (Node item:q) {
    System.out.println(item.getValue());
}
下面是该方法的另一种实现,不使用迭代器,我更喜欢:

List<String> q = new LinkedList<>();
q.add(root);

while(!q.isEmpty()) {
  Node node = q.poll();
  q.addAll(node.getChildren());
  System.out.println(node.getValue());
}
你绝对确定childs不是空的吗?你能把这个语句添加到你的代码System.out.printlnchilds.size中,在你说List childs=iter.next.GETCHILDS的那一行后面;让我知道它打印的是什么?此外,根据ConcurrentLinkedQueue的Java文档,不能保证iter会看到while循环中的更新。@CKing childs不是空的。我打印了childs的大小,结果是2个,即root的childs