Java如何在循环时添加到数组列表

Java如何在循环时添加到数组列表,java,arraylist,concurrentmodification,Java,Arraylist,Concurrentmodification,粒子类别: Exception in thread "Thread-2" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at biz.boulter.state.Menu.render(Menu.java:21

粒子类别:

Exception in thread "Thread-2" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at biz.boulter.state.Menu.render(Menu.java:21)
    at biz.boulter.sword.Game.render(Game.java:43)
    at biz.boulter.sword.Game.run(Game.java:136)
at java.lang.Thread.run(Unknown Source)
package biz.boulter.swarm;
导入java.awt.Color;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
公共类粒子{
私人双x=0;
私人双y=0;
私有双xa=0;
私人双ya=0;
私人色彩;
私有矩形img;
公共粒子(int x,int y,int xa,int ya,彩色){
这个.x=x;
这个。y=y;
这个.xa=xa;
this.ya=ya;
this.particlecolor=颜色;
img=新矩形(x,y,5,5);
}
公共无效渲染(图形2D g){
img.setBounds((int)Math.round(x),(int)Math.round(y),5,5);
g、 setColor(particlecolor);
g、 填充(img);
}
公共空白勾号(){
ya+=0.5;
if(xa<0){
xa+=1;
}
如果(xa>0){
xa-=1;
}
x+=xa;
y+=ya;
}
}

为了避免在集合的迭代中出现并发问题和
ConcurrentModificationException
,您必须使用并发集合类

例如,对于
ArrayList
,您可以尝试使用
CopyOnWriteArrayList
,这是
ArrayList
的线程安全变体


有关这方面的更多详细信息,请阅读此处:

为了避免在集合的迭代中出现并发问题和
ConcurentModificationException
,您必须使用并发集合类

例如,对于
ArrayList
,您可以尝试使用
CopyOnWriteArrayList
,这是
ArrayList
的线程安全变体


更多详细信息请阅读此处:

您有两个选项。如果可以,请将方法
勾选
渲染
鼠标按下
标记为
已同步
。这将解决问题,但如果插入速度更快,这可能不是最好的解决方案

另一个解决办法是改变

package biz.boulter.sword;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;

public class Particle {
private double x = 0;
private double y = 0;
private double xa = 0;
private double ya = 0;
private Color particleColour;
private Rectangle img;

public Particle(int x, int y, int xa, int ya, Color colour){
    this.x = x;
    this.y = y;
    this.xa = xa;
    this.ya = ya;
    this.particleColour = colour;
    img = new Rectangle(x, y, 5, 5);
}

public void render(Graphics2D g){
    img.setBounds((int)Math.round(x), (int)Math.round(y), 5, 5);
    g.setColor(particleColour);
    g.fill(img);
}

public void tick(){
    ya+=0.5;

    if(xa < 0){
        xa+=1;
    }

    if(xa > 0){
        xa-=1;
    }

    x+=xa;
    y+=ya;
}
}
private ArrayList particles=new ArrayList();

private LinkedBlockingQueue particles=new LinkedBlockingQueue();
这是因为,根据迭代器的方法:

返回的迭代器是一个“弱一致”迭代器,它将 永远不要抛出ConcurrentModificationException,并保证 遍历迭代器构造时存在的元素, 并且可能(但不保证)反映任何修改 施工之后


你有两个选择。如果可以,请将方法
勾选
渲染
鼠标按下
标记为
已同步
。这将解决问题,但如果插入速度更快,这可能不是最好的解决方案

另一个解决办法是改变

package biz.boulter.sword;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;

public class Particle {
private double x = 0;
private double y = 0;
private double xa = 0;
private double ya = 0;
private Color particleColour;
private Rectangle img;

public Particle(int x, int y, int xa, int ya, Color colour){
    this.x = x;
    this.y = y;
    this.xa = xa;
    this.ya = ya;
    this.particleColour = colour;
    img = new Rectangle(x, y, 5, 5);
}

public void render(Graphics2D g){
    img.setBounds((int)Math.round(x), (int)Math.round(y), 5, 5);
    g.setColor(particleColour);
    g.fill(img);
}

public void tick(){
    ya+=0.5;

    if(xa < 0){
        xa+=1;
    }

    if(xa > 0){
        xa-=1;
    }

    x+=xa;
    y+=ya;
}
}
private ArrayList particles=new ArrayList();

private LinkedBlockingQueue particles=new LinkedBlockingQueue();
这是因为,根据迭代器的方法:

返回的迭代器是一个“弱一致”迭代器,它将 永远不要抛出ConcurrentModificationException,并保证 遍历迭代器构造时存在的元素, 并且可能(但不保证)反映任何修改 施工之后


最简单的方法是在使用集合时锁定集合

private LinkedBlockingQueue<Particle> particles = new LinkedBlockingQueue<Particle>();

这样可以确保访问不是并发的

CopyOnWriteArrayList的问题在于写入成本很高。顾名思义,它在每次更新时都会复制整个列表


BlockingQueue的问题在于它不是为迭代而设计的。它可以工作,但效率不高。

最简单的方法是在使用集合时锁定集合

private LinkedBlockingQueue<Particle> particles = new LinkedBlockingQueue<Particle>();

这样可以确保访问不是并发的

CopyOnWriteArrayList的问题在于写入成本很高。顾名思义,它在每次更新时都会复制整个列表


BlockingQueue的问题在于它不是为迭代而设计的。它可以工作,但效率不高。

您试图更改数组的内部状态,而在循环时,这是预期的行为

一个快捷的方法(但会带来一些性能成本)是使用CopyOnWriteArrayList,请参阅链接条目,

您试图更改数组的内部状态,而循环时,这是预期的行为

一个快捷的方法(但会带来一些性能成本)是使用CopyOnWriteArrayList,请参阅链接条目,

在哪里捕获
ConcurrentModificationException
,显示stacktrace。如果在执行tick()或render()时捕获mousePressed事件,则在执行列表时将进行添加尝试,这是非法的。您需要实现一些并发安全机制。查找同步的信号量…好的,我添加了堆栈跟踪显示方法Particle.tick()和Particle.render()的代码。我认为问题就在这里。在哪里捕获ConcurrentModificationException,显示stacktrace。如果在执行tick()或render()时捕获mousePressed事件,则在执行列表时将进行添加尝试,这是非法的。您需要实现一些并发安全机制。查找同步的信号量…好的,我添加了堆栈跟踪显示方法Particle.tick()和Particle.render()的代码。我认为问题就在那里。
synchronized(particles) {
    for(Particle p: particles){
        p.tick();
    }
}
Particle p = new Particle(x, y, rand, Game.rand.nextInt(10)-11, new Color(Game.rand.nextInt(1000000000)))
synchronized(particles) {
    particles.add(p);
}