我环顾四周,但找不到我所遇到的问题的正确答案。我有一个不断修改和读取的列表,但我不断遇到并发问题。注意:有2个线程不断从此列表中提取数据。
问题会在doEntityTick()
和getEntity()
上弹出。注意:doEntityTick
问题是由我在列表中添加实体引起的。
世界:
package UnNamedRpg.World;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import UnNamedRpg.Player.Game.GameManager;
import UnNamedRpg.World.Entity.Entity;
import UnNamedRpg.World.Entity.EntityCharacter;
import UnNamedRpg.World.Entity.EntityLiving;
import UnNamedRpg.World.Entity.EntityProjectile;
public class World {
private String name;
private ArrayList<Boundary> boundList = new ArrayList<Boundary>();
private Collection<Entity> entityList = Collections.synchronizedList(new ArrayList<Entity>());
public World(String name){
setName(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Entity> getEntityList(){
ArrayList<Entity> newList = new ArrayList<Entity>();
synchronized(entityList) {
Iterator<Entity> iter = entityList.iterator();
while (iter.hasNext()) {
Entity ent = iter.next();
newList.add(ent);
}
}
return newList;
}
public ArrayList<Entity> getEntityAtCoordinatePair(double x, double y){
ArrayList<Entity> tempList = new ArrayList<Entity>();
for(Entity ent : getEntityList()){
Rectangle rect = new Rectangle((int)ent.getX(), (int)ent.getY(), ent.getWidth(), ent.getHeight());
if(rect.contains(x, y)){
tempList.add(ent);
}
}
return tempList;
}
public void addEntity(Entity ent){
synchronized(entityList){
entityList.add(ent);
if(ent.getID() == -1){
ent.setID(entityList.size());
}
}
}
public Entity getEntity(int id){
synchronized(entityList) {
Iterator<Entity> i = entityList.iterator();
while (i.hasNext()){
Entity ent = i.next();
if(ent.getID() == id){
return ent;
}
}
}
return null;
}
public void doEntityTick(){
synchronized(entityList) {
Iterator<Entity> iter = entityList.iterator();
while (iter.hasNext()) {
Entity ent = iter.next();
if(ent instanceof EntityLiving){
EntityLiving entLiv = (EntityLiving)ent;
if(entLiv.getHealth() <= 0){
entLiv.setDead();
}
if(entLiv.isDead() && entLiv.getHealth() > 0){
GameManager.isSpawning = true;
}
entLiv.doEntityTick();
}
if(ent instanceof EntityProjectile){
EntityProjectile entProj = (EntityProjectile)ent;
entProj.doTick();
entProj.setCurrentRange(entProj.getCurrentRange() + 1);
if(entProj.getCurrentRange() >= entProj.getRange()){
entProj.setDead();
}
}
if(ent.isDead() && !(ent instanceof EntityCharacter)){
iter.remove();
}
}
}
}
public void addBounds(Boundary bounds){
boundList.add(bounds);
}
public int getBoundsID(int x, int y){
for(int i=0;i<boundList.size();i++){
if(boundList.get(i).contains(x, y))
return i;
}
return -1;
}
public int getBoundsID(Boundary bounds){
for(int i=0;i<boundList.size();i++){
if(boundList.get(i) == bounds)
return i;
}
return -1;
}
public void removeBounds(Boundary bounds){
boundList.remove(bounds);
}
public Boundary getBounds(int x, int y){
for(Boundary bounds : boundList){
if(bounds.contains(x, y)){
return bounds;
}
}
return null;
}
public boolean isInBounds(int posX, int posY){
for(Boundary bounds : boundList){
if(bounds.contains(posX, posY)){
return true;
}
}
return false;
}
}
堆栈追踪:
Exception in thread "Thread-1" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at UnNamedRpg.World.World.doEntityTick(World.java:83)
at UnNamedRpg.Player.Game.GameManager$1.run(GameManager.java:49)
答案 0 :(得分:0)
所以经过一整天查看代码后,我设法找到了解决方法。它不是让实体立即产生,而是将它们粘在一个队列中并等待下一个世界滴答,以便产生它们。我感谢所有试图提供帮助的人,并给了那些帮助我找到答案的+1。