Iterator.next()上的游戏循环出现并发修改异常



我正在努力在我运行的游戏循环中解决这个问题。

我在Update()过程中有以下一个线程:

ListIterator<ExplosionClass> litr = Explosions.listIterator();
			while(litr.hasNext()){
		        ExplosionClass element = (ExplosionClass) litr.next();
				if (element.FinishedExplosion) {
					litr.remove();
				}
			}

我在litr.next()上间歇性地得到一个ConcurrentModificationException;

我正在通过另一个过程不时地将新项目添加到Explosions列表中。

我在第二个线程上的游戏循环如下:

public  void run() {
		Canvas canvas;
		Log.d(TAG, "Starting game loop");
		long beginTime;		// the time when the cycle begun
		long timeDiff;		// the time it took for the cycle to execute
		int sleepTime;		// ms to sleep (<0 if we're behind)
		int framesSkipped;	// number of frames being skipped 
		sleepTime = 0;
		
		// render state to the screen
		// draws the canvas on the panel
		
		while (running) {
		//while (!paused && running) {
			canvas = null;
			synchronized (this) {
                while (isPaused) {
                    try {
                        try {
            				canvas = this.surfaceHolder.lockCanvas();
                            synchronized (surfaceHolder) {
            					this.gamePanel.render(canvas);				
                            }
                            } finally {
                                if (canvas != null) {
                					surfaceHolder.unlockCanvasAndPost(canvas);
                                }
                        }
                        
                        this.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
			// try locking the canvas for exclusive pixel editing
			// in the surface
			try {
				canvas = this.surfaceHolder.lockCanvas();
				synchronized (surfaceHolder) {
					beginTime = System.currentTimeMillis();
					framesSkipped = 0;	// resetting the frames skipped
					// update game state 
					if (!isPaused && running) this.gamePanel.update();
					// render state to the screen
					// draws the canvas on the panel
					if (!isPaused) this.gamePanel.render(canvas);				
					// calculate how long did the cycle take
					timeDiff = System.currentTimeMillis() - beginTime;
					// calculate sleep time
					sleepTime = (int)(FRAME_PERIOD - timeDiff);
					
					if (sleepTime > 0) {
						// if sleepTime > 0 we're OK
						try {
							// send the thread to sleep for a short period
							// very useful for battery saving
							Thread.sleep(sleepTime);	
						} catch (InterruptedException e) {}
					}
					
					while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
						// we need to catch up
						// update without rendering
						if (!isPaused && running) this.gamePanel.update(); 
						// add frame period to check if in next frame
						sleepTime += FRAME_PERIOD;	
						framesSkipped++;
					}
				}
			} finally {
				// in case of an exception the surface is not left in 
				// an inconsistent state
				if (canvas != null) {
					surfaceHolder.unlockCanvasAndPost(canvas);
				}
			}	// end finally
		} 
		
		try {
			Thread.sleep(FRAME_PERIOD);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	//}  
	} 

事实上,你不能这样做:当你使用迭代器、同步或其他锁定机制对列表进行迭代时,你必须确保其他线程没有更改列表。

问题是,如果两个迭代器同时修改集合的内部结构,会导致ConcurrentModification异常。要处理此问题,请使用同步集合(CopyOnWriteArrayList)

在列表上调用迭代器时,迭代器工作时无法对其进行修改。

最新更新