我正在制作一个程序,模拟派对中的字符,检查/输出属于整个派对的ArrayList所需的工件。在我的生物将他们的物品放入聚会ArrayList然后遍历它寻找正确的工件后,我得到了一个并发修改异常。
这就是我的流程:最初所有角色都是使用随机的Artifacts创建的。执行作业时,它将检查它是否具有正确数量的工件。如果确实如此,它将完成这项工作,并将其拥有的所有工件发布到各方ArrayList中。如果没有,那么它将等待机会使用各方ArrayList,并且当它有机会将其所有项目放入其中并迭代以获得正确的项目。
注意:一次只有一个生物可以与各方ArrayList互动
这是我的代码位于线程本身,以确保所有线程合作:
boolean ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
//checks to see if creature already has correct amount of each item
while ( !ready ) {//begin pool interaction
synchronized ( target.poolParty ){
while ( target.poolParty.busyPool ) {//busyPool is initialized false
startJob.setEnabled( false );
startJob.setText( "Waiting for Pool");
try {
target.wait();
} catch ( InterruptedException e ) {}
}
synchronized ( target.poolParty ) {
target.poolParty.busyPool = true;
target.poolParty.notifyAll();//notify all threads that they need to wait because this one will proceed
}
}
target.releaseArtifacts();// adds all artifacts held by creature to an arraylist in poolParty
//then clears the creatures inventory
target.pickUpArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
//Searches through poolParty's ArrayList of artifacts for required artifacts
ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
if ( ready ) {
synchronized ( target.poolParty ) {
target.poolParty.busyPool = false;
target.poolParty.notify();
}
} else {
synchronized ( target.poolParty ) {
target.poolParty.busyPool = false;
target.releaseArtifacts();
target.poolParty.notify();
}
}
}//end pool interaction
在调用“releaseArtifacts”后调用“pickUpArtifacts”方法时代码中断了 下面是我的方法pickUpArtifacts:
public void pickUpArtifacts ( int stones, int potions, int wands, int weapons ){
hasReqArtifacts( stones, potions, wands, weapons );
String theType;
if ( !poolParty.resourcePool.isEmpty() ) {//itterate through whole pool to see if it can get needed items
for ( Artifact a : poolParty.resourcePool ) {//This is where the code breaks
theType = a.getType();
if ( theType.equals( "Stone" ) && ( curStones < stones )) {
addArtifact( a );
poolParty.resourcePool.remove( a );
} else if ( theType.equals( "Potion" ) && ( curPotions < potions ) ) {
addArtifact( a );
poolParty.resourcePool.remove( a );
} else if ( theType.equals( "Wand" ) && ( curWands < wands )) {
addArtifact( a );
poolParty.resourcePool.remove( a );
} else if ( theType.equals( "Weapon" ) && ( curWeapons < weapons )) {
addArtifact( a );
poolParty.resourcePool.remove( a );
}
}
}
hasReqArtifacts( stones, potions, wands, weapons );
}
最初我使用锁来尝试同步。这最终导致了同样的错误,所以我使用类似于我用来杀死线程的布尔标志的同步代码来接近它。在那之后不起作用我精确地调整了代码执行的位置,以便在迭代期间不会操纵ArrayList。
它继续抛出与以前相同的错误。它甚至在同一过程中崩溃。我似乎无法弄清楚什么是错的。
答案 0 :(得分:2)
迭代时不能修改集合。在这种情况下,它与多个线程无关。
请注意,您正在迭代这个集合
for ( Artifact a : poolParty.resourcePool )
然后,在for块中,您尝试从同一个集合中删除
poolParty.resourcePool.remove( a );
要在这种情况下有效地从列表中删除,请使用Iterator
和迭代器remove
方法。
答案 1 :(得分:-1)
创建列表时,您应该使用下一个代码,
List yourList = Collections.synchronizedList(new ArrayList())
(在同步块/方法内)