I'm making a program that simulates characters in a party checking in / out Artifacts they require for jobs from an ArrayList that belongs to the whole party. After my creatures drop their items into the parties ArrayList and then iterate through it looking for the correct Artifacts I get a Concurrent Modification exception.
This is how I have it flow: Initially all characters are created with a random assortment of Artifacts. When performing a job it will check if it has the correct amount of Artifact. If it does it will do the job, and release all the artifacts it has into the parties ArrayList. If it does not it will then wait for a chance to use the parties ArrayList and when given the chance it will drop all its items into it and iterate through for the correct Items.
Note: only one creature may interact with the parties ArrayList at a time
This is my code located in the thread itself for making sure all the the threads cooperate:
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
The code breaks when I call the "pickUpArtifacts" method after calling "releaseArtifacts" Below is my method 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 );
}
Initially I was using attempting synchronization using locks. This ended up throwing the same error so I approached it with synchronized code with boolean flags similar to what I use for killing the thread. After that did not work I fine tuned exactly where the code was performing so that nothing would manipulate the ArrayList during iteration.
It continues to throw the same error as before. It even breaks down during the same process. I cant seem to figure out whats wrong.
Listwhile iterating over it. That's exactly what should happen. Use an iterator and its methods.