Java 在遍历对象时从列表中删除对象
我目前正在制作一个游戏,要编辑/删除/添加我的所有实体,我有一个数组列表。每一帧每秒60倍更新和渲染列表中的所有内容。当我在entities update方法中调用要添加或删除的对象时,我在Thread-2中收到一个错误。通过一些快速的研究,我发现在迭代列表时编辑列表是不正确的。这就是我目前遇到的问题吗?还是因为我的列表不是线程安全的 渲染方法:Java 在遍历对象时从列表中删除对象,java,arraylist,linked-list,hashmap,Java,Arraylist,Linked List,Hashmap,我目前正在制作一个游戏,要编辑/删除/添加我的所有实体,我有一个数组列表。每一帧每秒60倍更新和渲染列表中的所有内容。当我在entities update方法中调用要添加或删除的对象时,我在Thread-2中收到一个错误。通过一些快速的研究,我发现在迭代列表时编辑列表是不正确的。这就是我目前遇到的问题吗?还是因为我的列表不是线程安全的 渲染方法: public void render(Graphics g){ for(Entity entity: list){ en
public void render(Graphics g){
for(Entity entity: list){
entity.render(g);
}
}
更新方法:
public void update(){
for(Entity entity: list){
entity.update();
}
}
如果我的问题是在更新列表时编辑列表,这是如何解决的
public void update(){
for(Entity entity: list){
entity.update();
}
for(Entity entity: removeList){
list.remove(entity);
}
removeList.clear();
}
还是因为我的列表不是线程安全的
是,如果渲染和更新可以在不同线程上同时运行
这是怎么解决的
不,仍然是相同的问题,您将尝试在迭代时删除
或者
构建一个新列表,其中只包含要保留的条目,然后将其替换为更新对象引用的列表是原子的,或者
同步列表中渲染和更新方法的相关部分
下面是1的一个粗略示例:
public void update(){
List newList = new AppropriateListType(list);
for (Entity entity : removeList){
newList.remove(entity);
}
removeList.clear(); // Or removeList = new AppropriateListType();
list = newList;
for (Entity entity: list) {
entity.update();
}
}
注:我颠倒了这两个循环的顺序;大概在更新您将要删除的实体时没有什么意义
这是因为在我们修改新列表时,没有任何东西可以尝试迭代它,因为在我们执行list=newList之前,新列表对于update方法的这个特定执行是完全私有的。一旦我们执行list=newList,它就在对象上,所以其他代码将尝试使用它
还有一个粗略的例子2:
public void update(){
synchronized (list) {
for (Entity entity: removeList){
list.remove(entity);
}
}
removeList.clear();
for (Entity entity: list) {
// This is probably fine depending on how `render` and `update` work
// but you *may* need to `synchronize` on `entity` (here and in `render`
// depending on how `render` and `update` work
entity.update();
}
}
同样,循环是反向的
有关中同步的详细信息
旁注:您可能还需要检查removeList的迭代和更新。Crowder如果我的列表不安全,是否可以使用其他线程类型?我将如何同步列表中的相关部分?@MaxwellBrookes-您将执行我上面描述的操作…?ArrayList是合适的列表类型吗?或者它必须是一个同步的列表?@MaxwellBrookes-如果你在做上面的事情,不需要使用其中一个内置同步的列表。因此,无论什么列表类型适合您所做的事情。您得到的确切错误消息是什么?哪一行导致它?寻求调试帮助的问题为什么这段代码不起作用?必须包括所需的行为、特定的问题或错误以及在问题本身中重现这些问题所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参见:如何创建。使用链接改进您的问题-不要通过评论添加更多信息。谢谢