編輯:好吧,我覺得很羞怯。我在看錯誤的構造函數。根據Kal的回答,被調用的真正構造函數(見下文)違反了foreach循環的併發規則。ConcurrentModificationException對單線程代碼
謝謝你的幫助不管!它仍然可以幫助我修復代碼中的實際錯誤。
所有
我是一個相當新的Java程序員,和我纔剛剛開始獲得的語言基本手柄。我目前正在與對話參與者系統合作,但首先試圖讓我們的系統對邏輯術語的表示達到規範。我幾乎完成,但遇到了以下錯誤:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at com.Term.<init>(Term.java:97)
at com.Term.substituteVariables(Term.java:251)
at com.Term.substituteVariables(Term.java:247)
at com.Term.substituteVariables(Term.java:247)
at com.TermPredTestArch.main(TermPredTestArch.java:40)
問題,substituteVariables的方法,基本上是拷貝構造函數,有輕微的修改:它需要在地圖上的綁定,並遞歸迭代通過它從中調用的術語對象,沿途找到變量並將它們交換出來用於實例化。奇怪的是,當我離開的時候(雖然我沒有廣泛測試),它似乎只是在昨天晚上才工作,但現在拒絕演奏很好;我沒有做出實質性的修改。
相關的代碼如下(行232-252):
232 /** Returns a new Term with the appropriate bindings substituted */
233 public Term substituteVariables(Map<Variable, Symbol> bindings) {
234 ArrayList<Symbol> args = this.getArgs();
235 ArrayList<Symbol> newArgs = new ArrayList<Symbol>();
236 Set<Variable> vars = this.getVars();
237 Set<Variable> bindingKeys = bindings.keySet();
238 for(Symbol s: args) {
239 // if s is a Variable, check to see if it has a substituion, and
240 // if so, swap it out
241 if(s instanceof Variable) {
242 if(bindingKeys.contains(s)) newArgs.add(bindings.get(s));
243 else newArgs.add(s);
244 // if s is a Term, add it and recursively substitute any variables
245 // it has within the current set of bindings
246 } else if(s instanceof Term) {
247 newArgs.add(((Term) s).substituteVariables(bindings));
248 // if s is just a symbol, simply add it to the args
249 } else newArgs.add(s);
250 }
251 return new Term(this.getName(), newArgs);
252 }
編輯:這裏是爲期限的構造:
public Term(String n, ArrayList<Symbol> a) {
super(n);
args = a;
HashSet<Variable> varsToAdd = new HashSet<Variable>();
for(Symbol s: a) parseArg(s.toString());
}
這是-actual-構造,這是被稱爲,而不是我認爲被稱爲的那個。根據Kal的回答,事實上,這違反了foreach循環併發規則。
從我已經完成的研究中,我知道ConcurrentModificationException通常是由多個線程在沒有同步的情況下同時迭代/修改一個Collection引起的,但我沒有故意的並行性,也沒有任何其他地方的類或測試使用它的代碼。否則,我不完全確定。該類的javadoc提到它也可能是迭代器同時迭代和修改一個Collection的原因,但我不認爲我也這麼做;我只是觀察迭代的Collection並使用它的信息來構建另一個Collection。這是否違反併發規定?
任何你可能能夠提供的指針將非常感謝!我也會爲任何嚴重違反Java禮節或風格的行爲先發制人地道歉(請隨時指出這些行爲!)。
感謝,當你同時通過它使用了迭代循環修改一個ArrayList發生
我認爲你需要顯示的期限構造,因爲那正是把它扔。 – Anon
「Term」的構造函數是什麼樣的?這就是拋出異常的地方。 –
加入;謝謝 –