Java 如何解决此ConcurrentModificationException

Java 如何解决此ConcurrentModificationException,java,concurrentmodification,Java,Concurrentmodification,我正在尝试在我的应用程序中实现一种算法来生成BSP树。我遇到的问题是,我需要循环遍历每个“父”的所有“子”项,将它们拆分并将这些子项添加到列表中,然后继续遍历这些子项 我不知道如何使用并发修改来实现这一点 public void generate() { Parent root = new Parent(0, 0, width, height); parents.add(root); boolean did_split = true; while (did_s

我正在尝试在我的应用程序中实现一种算法来生成BSP树。我遇到的问题是,我需要循环遍历每个“父”的所有“子”项,将它们拆分并将这些子项添加到列表中,然后继续遍历这些子项

我不知道如何使用并发修改来实现这一点

public void generate() {
    Parent root = new Parent(0, 0, width, height);
    parents.add(root);

    boolean did_split = true;

    while (did_split) {
        did_split = false;
        for (Parent p : parents) {
            if (p.leftChild == null && p.rightChild == null) {
                if (p.width > MAX_SIZE || p.height > MAX_SIZE || Math.random() > 0.25) {
                    if (p.split()) {
                        parents.add(p.leftChild);
                        parents.add(p.rightChild);
                        did_split = true;
                    }
                }
            }
        }
    }   
}

parents是类中前面定义的ArrayList。

因为您有一个
ArrayList
,所以可以使用它的。由于无法使用普通的
迭代器
(这是增强版for在引擎盖下使用的)向正在迭代的内容添加新值,因此使用
列表迭代器
可以访问
添加
方法

你还需要做更多的工作,让它在你期望的地方插入东西;也就是说,您必须将光标向后移动一个位置,以便迭代可以继续(因为您受到迭代器中是否有要继续迭代的元素的限制)

for (ListIterator<Parent> iterator = parents.listIterator(); iterator.hasNext(); ) {
    Parent p = iterator.next();
    if (p.leftChild == null && p.rightChild == null) {
        if (p.width > MAX_SIZE || p.height > MAX_SIZE || Math.random() > 0.25) {
            if (p.split()) {
                parents.add(p.leftChild);
                iterator.previous();
                parents.add(p.rightChild);
                iterator.previous();
                did_split = true;
            }
        }
    }
}
for(ListIterator iterator=parents.ListIterator();iterator.hasNext();){
父p=iterator.next();
if(p.leftChild==null&&p.rightChild==null){
如果(p.width>MAX|u SIZE | p.height>MAX|u SIZE | Math.random()>0.25){
如果(p.split()){
添加(p.leftChild);
迭代器.previous();
添加(p.rightChild);
迭代器.previous();
_split=true;
}
}
}
}

这并不优雅…但可能有用…可能使用信号量并将进行修改的代码部分放在synchronized(){}块中?请参见此处如何使用synchronized关键字:我在发布问题后大约10分钟就尝试过了。运气不好。将其包围在synchronized(){}块中块,以及创建synchronizedList()从原始列表开始,使用它,并使函数本身同步。这可能无法解决您的问题,但请查看答案,以了解有关列表并发实现的一些信息。此外,在迭代一个iterable并同时编辑iterable时,使用迭代器更安全……或者更确切地说,不使用迭代器并不安全fe.1Darco1,我将您发布的答案中的家长列表更改为CopyOnWriteArrayList,现在效果很好,谢谢!