Java ConcurrentModificationException而I';I’我正在尝试将一个项目添加到集合中

Java ConcurrentModificationException而I';I’我正在尝试将一个项目添加到集合中,java,android,Java,Android,我花了一整天的时间试图解决这个问题。我试着使用iTertion?同步,还有很多其他的萨满方法,但我一直在得到ConcurrentModificationException。下面是代码 package com.androidgui.test; import java.util.ArrayList; import java.util.ListIterator; import android.app.AlertDialog; import android.content.Context; impo

我花了一整天的时间试图解决这个问题。我试着使用iTertion?同步,还有很多其他的萨满方法,但我一直在得到ConcurrentModificationException。下面是代码

package com.androidgui.test;

import java.util.ArrayList;
import java.util.ListIterator;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
import android.widget.Toast;

public class CustomView extends SurfaceView implements Callback {
    private UpdateThread thread;
    private AButton btn;
    private AWindow wnd;
    private ArrayList<AControl> globalControls;
    private Object sync;
    public static int posX;
    public static int posY;

    public CustomView(Context context) {
        super(context);
        this.getHolder().addCallback(this);
        this.LoadResourse();
        sync =  new Object();
        this.globalControls = new ArrayList<AControl>();
        btn = new AButton(10, 10,null,AControl.InterfaceImages.Button); 
        this.globalControls.add(btn);
        wnd = new AWindow(10, 10, 200, 100, null);
        this.SetDelegates();

    }
    private void LoadResourse()
    {
        AControl.InterfaceImages.Button = BitmapFactory.decodeResource(getResources(), R.drawable.button);
    }
    private void SetDelegates()
    {
        btn.setEventHandler(new EventHandler() {

            @Override
            public void ProcessEvent() {
                synchronized (sync) {
                    globalControls.add(wnd);
                }
            }
        });
    }
    @Override
    public void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        posX = (this.getWidth()- AControl.InterfaceImages.Button.getWidth()) /2;
        posY = (this.getHeight()- AControl.InterfaceImages.Button.getHeight()) /2;
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        thread = new UpdateThread(this.getHolder(), this);
        thread.setRunning(true);
        thread.start();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        thread.setRunning(false);
        boolean _retry=true;
        try
        {
        while(_retry)
        {
            thread.join();
            _retry=false;
        }
        }catch(Exception ex)
        {

        }
    }
    public boolean onTouchEvent(MotionEvent event)
    {
        synchronized (sync) {
            for(AControl item :this.globalControls)
                item.onClick(event);
        }

        return true;
    }
    public void onDraw(Canvas canvas)
    {
        synchronized (sync) {   
        ArrayList<AControl> temp  = (ArrayList<AControl>) this.globalControls.clone();
            for(AControl item :temp)
                item.onDraw(canvas);
        }
    }

}
package com.androidgui.test;
导入java.util.ArrayList;
导入java.util.ListIterator;
导入android.app.AlertDialog;
导入android.content.Context;
导入android.content.DialogInterface;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.os.Message;
导入android.util.Log;
导入android.view.MotionEvent;
导入android.view.SurfaceHolder;
导入android.view.SurfaceView;
导入android.view.SurfaceHolder.Callback;
导入android.widget.Toast;
公共类CustomView扩展了SurfaceView实现回调{
私有UpdateThread线程;
私人阿布顿btn;
私人公寓;
私有ArrayList全局控制;
私有对象同步;
公共静态int-posX;
公共静态整数;
公共自定义视图(上下文){
超级(上下文);
this.getHolder().addCallback(this);
这是loadresource();
sync=新对象();
this.globalControls=new ArrayList();
btn=新的AButton(10,10,null,一个控件接口图像按钮);
this.globalControls.add(btn);
wnd=新的AWindow(10,10,200,100,null);
这个.SetDelegates();
}
私有void loadresource()
{
AControl.interfaceeimages.Button=BitmapFactory.decodeResource(getResources(),R.drawable.Button);
}
私有void SetDelegates()
{
setEventHandler(新的EventHandler(){
@凌驾
public void ProcessEvent(){
已同步(同步){
globalControls.add(wnd);
}
}
});
}
@凌驾
已更改尺寸上的公共空隙(整数w、整数h、整数oldw、整数oldh)
{
posX=(this.getWidth()-AControl.InterfaceImages.Button.getWidth())/2;
posY=(this.getHeight()-AControl.InterfaceImages.Button.getHeight())/2;
}
@凌驾
公共无效表面更改(表面更改arg0、int arg1、int arg2、int arg3){
//TODO自动生成的方法存根
}
@凌驾
已创建公共空白表面(表面文件夹arg0){
thread=newupdatethread(this.getHolder(),this);
thread.setRunning(true);
thread.start();
}
@凌驾
公共空间表面已覆盖(表面层arg0){
thread.setRunning(false);
布尔值_retry=true;
尝试
{
while(\u重试)
{
thread.join();
_重试=错误;
}
}捕获(例外情况除外)
{
}
}
公共布尔onTouchEvent(运动事件)
{
已同步(同步){
for(a控制项:this.globalControls)
item.onClick(事件);
}
返回true;
}
公共空白onDraw(画布)
{
已同步(同步){
ArrayList temp=(ArrayList)this.GlobalControl.clone();
用于(A控制项:临时)
项目.onDraw(帆布);
}
}
}

迭代集合时(从同一线程或从另一线程)不能修改集合


您需要创建一个迭代的副本(
new ArrayList(existingList)
),或者使用
CopyOnWriteArrayList

在迭代集合时(从同一线程或从另一线程)无法修改集合


您需要复制一个迭代的副本(
new ArrayList(existingList)
),或者使用
CopyOnWriteArrayList

您在此处克隆了列表:

 public void onDraw(Canvas canvas)
    {
        synchronized (sync) {   
        ArrayList<AControl> temp  = (ArrayList<AControl>) this.globalControls.clone();
            for(AControl item :temp)
                item.onDraw(canvas);
        }
    }

我想这就是问题所在。但是,您没有包含堆栈跟踪的事实使猜测变得更加困难。添加同步不会解决您的问题,因为问题在于您可能在遍历列表时修改了它。

您在此处克隆了列表:

 public void onDraw(Canvas canvas)
    {
        synchronized (sync) {   
        ArrayList<AControl> temp  = (ArrayList<AControl>) this.globalControls.clone();
            for(AControl item :temp)
                item.onDraw(canvas);
        }
    }

我想这就是问题所在。但是,您没有包含堆栈跟踪的事实使猜测变得更加困难。添加同步不会解决您的问题,因为问题在于您可能在遍历列表时修改了列表。

ConcurrentModificationException的意思是,在使用迭代器或增强的for循环遍历集合时,您尝试在集合中添加或删除元素

乙二醇

你应该写

ArrayList<AControl> copy;
synchronized (sync) {   
    copy = (ArrayList<AControl>) globalControls.clone();
    // exit synchronised block as we no longer need to be synchronised 
    // as we have a copy of the list now
}

for(AControl item : copy) {
    item.onDraw(canvas);
}
ArrayList副本;
已同步(同步){
copy=(ArrayList)globalControls.clone();
//退出同步块,因为我们不再需要同步
//因为我们现在有一份名单
}
用于(A控制项:副本){
项目.onDraw(帆布);
}

ConcurrentModificationException意味着,在使用迭代器或增强的for循环对集合进行迭代时,您试图从集合中添加或删除元素

乙二醇

你应该写

ArrayList<AControl> copy;
synchronized (sync) {   
    copy = (ArrayList<AControl>) globalControls.clone();
    // exit synchronised block as we no longer need to be synchronised 
    // as we have a copy of the list now
}

for(AControl item : copy) {
    item.onDraw(canvas);
}
ArrayList副本;
已同步(同步){
copy=(ArrayList)globalControls.clone();
//退出同步块,因为我们不再需要同步
//因为我们现在有一份名单
}
用于(A控制项:副本){
项目.onDraw(帆布);
}
ArrayList<AControl> copy;
synchronized (sync) {   
    copy = (ArrayList<AControl>) globalControls.clone();
    // exit synchronised block as we no longer need to be synchronised 
    // as we have a copy of the list now
}

for(AControl item : copy) {
    item.onDraw(canvas);
}