我有一个类A,里面有个 public static ArrayList<Missile> missiles=new ArrayList<Missile>();的属性类A里的paint有个for-each循环,不停的在画图,如下
for(Missle a:missiles)
  g.drawImage(xxxxxxx);问题来了,如果有其他线程使用missile.add(Missile xx)
就报concurrent异常,请问如何解决啊?考虑2天了!!

解决方案 »

  1.   

    写自己的MyArrayList extends ArrayList。
    然后将add等方法声明成synchronized。
      

  2.   

    同步 或者直接用 Lock lock = new ReentrantLock() 锁住信息共享操作的那一块
      

  3.   

    missile.add(Missile xx);
    改成synchronized(missile){
        missile.add(Missile xx);
    }
    试一下。
      

  4.   

    Mark顶贴是一种美德,O(∩_∩)O~
      

  5.   

    synchronize只能防止多个线程同时add,问题是,我一个线程在对missiles做for_each循环,一个线程在对missile做增加操作啊!还是有并发问题的
      

  6.   

    如果遍历的操作远远大于 add 的操作的话,可以改成:java.util.concurrent.CopyOnWriteArrayList 这个类。否则的话需要进行互斥处理。
      

  7.   

    不是missile.add(Missile xx); 
    而是missiles.add(Missile xx); ????再完整点的代码看一下,有些不太明白你程序的意思。
      

  8.   

    或者使用 Collections.synchronizedList 包装成同步的 List
      

  9.   


    不好意思,第一贴写错了,是missiles.add(Missile xx)
      

  10.   

    missile.add(Missile xx); 
    改成 synchronized(missile){ 
        missile.add(Missile xx); 

    然后
    for(Missle a:missiles) 
      g.drawImage(xxxxxxx); 
    改成
    for(Missle a:missiles) {
      synchrinized(g)
      g.drawImage(xxxxxxx); 
    }再试下。
      

  11.   

    我觉得可以把画图的for(Missle a:missiles) 
      g.drawImage(xxxxxxx); 单独放在一个线程中,执行missiles.add(Missile xx)时暂停上面的线程。add完后notify上面线程重新开始执行画图。
      

  12.   

    List 接口下有 ArrayList 和VectorArrayList不是现成安全的,而Vector是现成安全的。为什么呢?很简单,打开源码看看同样的实现Vector的方法前加了 synchronized 关键字
      

  13.   

    可能我之前说的不清楚,我把部分代码贴一下:
    class A extends JComponent{
    private ArrayList<Missile> missiles = new ArrayList<Missile>();
    private ArrayList<RivalTank> rivaltanks = new ArrayList<RivalTank>(); public void addMissile(Missile singleMissile) {
    synchronized (missiles) {
    missiles.add(singleMissile);
    }
    }public void paint(Graphics g) {
    super.paint(g);
    setBackground(Color.BLACK);
    if (image == null)
    return;
    try {
    for (Missile mil : getMissiles()) { if (mil.isDistory() == false)
    g.drawImage(mil.getImage(), mil.getMissileX(), mil
    .getMissileY(), null);
    }
    for (RivalTank rivaltank : rivaltanks) {
    if (rivaltank.isDistory() == false)
    g.drawImage(rivaltank.getImage(), rivaltank.getX(),
    rivaltank.getY(), null);
    }
    } catch (Exception e) {
    e.printStackTrace();
    // System.out.println("Can't fire");
    } }
    }
    然后有个Runnable线程
    Class B implements Runnable{
    public void run() {

    while (rivaltank.isDistory()==false) {

    rivaltank.move(jf.getBounds());
    if(rivaltank.getRandom()==2){
    Missile singleMissile=new Missile(rivaltank.getDir(),rivaltank.getX(),rivaltank.getY(),50
    ,50);
    tank.addMissile(singleMissile);
    Thread th=new Thread(new MissileRun(tank,singleMissile));
    th.start();

    }
    tank.repaint();
    try {
    Thread.sleep(100);
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    }

    } }
    }就是tank.addMissile(singleMissile);这加入一个Missile实例,导致concurrent
      

  14.   

    java.util.ConcurrentModificationException异常我用了各种锁也锁不住,郁闷
      

  15.   

    你也可以自己做缓冲区啊。
    每次循环结束后去check缓冲区中的内容。有则add。其他的地方都写到缓冲区中。
      

  16.   


    信息共享那块是个属性,怎么锁啊?
    我试过将getMissiles()改成
    ArrayLsit getMissiles(){
      synchronized(missiles){
        return missiles;
    }
    }然后增加的时候用A.getMissiles().add(new Missile()),然后paint里的for-each改成
    for(Missile:getMissiles())还是报错