パーティー全体に属するArrayListからのジョブに必要なアーティファクトをチェックイン/アウトするパーティーのキャラクターをシミュレートするプログラムを作成しています。私のクリーチャーがアイテムをパーティの ArrayList にドロップし、それを反復処理して正しいアーティファクトを探した後、同時変更例外が発生します。
これが私の流れです。最初は、すべてのキャラクターがアーティファクトのランダムな組み合わせで作成されます。ジョブを実行すると、アーティファクトの量が正しいかどうかがチェックされます。もしそうなら、それは仕事をし、それが持っているすべてのアーティファクトをパーティーArrayListに解放します。そうでない場合は、パーティの ArrayList を使用する機会を待ち、機会があればすべての項目をそこにドロップして、正しい項目を反復処理します。
注:一度に 1 つのクリーチャーのみがパーティの 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 を操作しないようにしました。
以前と同じエラーをスローし続けます。同じプロセスで壊れることさえあります。何が悪いのか理解できないようです。