2015-06-28 89 views
0

我試圖實現一種算法來在我的應用程序中生成BSP樹。我遇到的問題是我需要遍歷每個「父」的所有「子」,並將它們分開並將這些子添加到列表中,並繼續遍歷子元素。如何解決此問題ConcurrentModificationException

我迷失在如何使用併發修改做到這一點。

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; 
        } 
       } 
      } 
     } 
    } 
} 

父母是一個ArrayList,它是在類中更早定義的。

+0

這不是優雅.. 。但可能工作...也許使用信號量,並將修改的代碼段放入同步(){}塊中?請參見此處如何使用synchronized關鍵字: http://stackoverflow.com/問題/ 5861894/how-to-synchronization-or-lock-upon-variables-in-java –

+0

我發佈這個問題後約10分鐘試過,沒有運氣,將它包含在一個synchronized(){}塊中,以及從原始列表創建synchronizedList()並使用它,並使函數本身同步編輯。 – Darren

+0

這可能無法解決您的問題,但請查看[this](http://stackoverflow.com/a/http://stackoverflow.com/a/6916419)回答關於列表的同時實施的一些信息。 – 1Darco1

回答

2

既然你有一個ArrayList,你可以使用其ListIterator。由於您無法使用普通的Iterator(這是增強功能在底層使用的內容)迭代的內容添加新值,因此使用ListIterator可以訪問add方法。

您還需要做更多的工作才能讓它在您期望的地方插入東西;也就是說,你必須將光標移回到一個位置,以便迭代可以繼續(因爲你的迭代器中是否有元素可以繼續迭代)。

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; 
      } 
     } 
    } 
}