错误java.util.ConcurrentModificationException

news/2024/7/6 13:41:01 标签: android, cocos2d-x

现象描述:

cocos2d-x游戏移植android平台,运行时出现闪退,log如下:

06-17 13:12:25.020: E/AndroidRuntime(8053): FATAL EXCEPTION: GLThread 273
06-17 13:12:25.020: E/AndroidRuntime(8053): java.util.ConcurrentModificationException
06-17 13:12:25.020: E/AndroidRuntime(8053): 	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:792)
06-17 13:12:25.020: E/AndroidRuntime(8053): 	at java.util.HashMap$KeyIterator.next(HashMap.java:819)
06-17 13:12:25.020: E/AndroidRuntime(8053): 	at org.cocos2dx.lib.Cocos2dxSound.stopEffect(Cocos2dxSound.java:176)
06-17 13:12:25.020: E/AndroidRuntime(8053): 	at org.cocos2dx.lib.Cocos2dxHelper.stopEffect(Cocos2dxHelper.java:185)
06-17 13:12:25.020: E/AndroidRuntime(8053): 	at org.cocos2dx.lib.Cocos2dxRenderer.nativeRender(Native Method)
06-17 13:12:25.020: E/AndroidRuntime(8053): 	at org.cocos2dx.lib.Cocos2dxRenderer.onDrawFrame(Cocos2dxRenderer.java:94)
06-17 13:12:25.020: E/AndroidRuntime(8053): 	at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
06-17 13:12:25.020: E/AndroidRuntime(8053): 	at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

原因分析:

查看Cocos2dxSound.java的176行stopEffect方法

	public void stopEffect(final int pStreamID) {
		this.mSoundPool.stop(pStreamID);

		// remove record
		for (final String pPath : this.mPathStreamIDsMap.keySet()) {
			if (this.mPathStreamIDsMap.get(pPath).contains(pStreamID)) {
				this.mPathStreamIDsMap.get(pPath).remove(this.mPathStreamIDsMap.get(pPath).indexOf(pStreamID));
				break;
			}
		}
	}

我们注意到,在迭代时有remove操作,即进行了结构修改(增删操作),快速失败,因此抛出了ConcurrentModificationException.


解决方法:

由于我的游戏里的这个音效频繁播放,所以我用pauseEffect替代了stopEffect,一个偷懒的方案.

彻底的解决方法:

1).使用iterator来修改vector

2).使用conCurrentHashMap替代HashMap


扩展阅读:

快速失败:指某个线程在迭代vector的时候,不允许其他线程对vector进行结构性修改(增删操作,改值不算),如有修改,会抛出ConcurrentModificationException异常.

比如用iterator迭代userCollect时,iterator即另外起的一个线程,如果此时用userCollect.remove(obj)修改userCollect时,就会立刻抛出异常报错,不会等迭代结束才报错.

即时是单线程里,也是这样的.






http://www.niftyadmin.cn/n/1691510.html

相关文章

python中args和kwargs_Python中*args和**kwargs的区别

(注:本文部分内容摘自互联网,由于作者水平有限,不足之处,还望留言指正。)中秋的夜,微凉,但却始终看不见月亮。我想,它一定是害羞了,悄悄的躲到了乌云的后面。嗯,就是这样…

quick-cocos2d-x -2 打不开player.app

现象描述: quick-cocos2d-x平台, - 运行 setup_mac.sh - 启动 player/mac/player.app 弹出错误提示窗口: 打不开"player.app"。您应该将它移到废纸篓。 解决方法: 选中player.app,鼠标右键显示包…

python推荐算法库surprise_Python推荐系统库--Surprise理论

SurpriseSurprise是scikit系列中的一个。Surprise的User Guide有详细的解释和说明支持多种推荐算法下面介绍几种算法基础算法:说明:Algorithm predicting a random rating based on the distribution of the training set, which is assumed to be norma…

linux下生成jre

前言: ava平台的领导者们意识到了随着虚拟化、容器化、微服务化的普及和流行,以前庞大的JRE已经跟不上时代的发展:作为一个运行时,里面经常包含了太多不需要的东西。比如,如果一台主机上的某个JRE仅仅是用来运行Apach…

HideInInspector 与SerializeField

[HideInInspector]表示将原本显示在面板上的序列化值隐藏起来。[SerializeField]表示将原本不会被序列化的私有变量和保护变量可以序列化,这么他们在下次读取时,就是你上次赋值的值。1如果a是公有的序列化变量。1.1如果你想要在面板中看到a,那…

LUbuntu16.10安装及自动使用root登录(Ubuntu类似)

本文转载自博客作者:lyatdawn,点击查阅原文。 LUbuntu是一款新的轻量级Ubuntu发行版,结合LXDE使得LUbuntu安装、运行速度极快,硬件资源要求很低,支持X86和ARM架构处理器。 可以在http://lubuntu.net/根据自己电…

word文档怎么一分为二_word文档怎么加边框和底纹-给文档化个妆

​word,不但可以给文字或者段落添加边框和底纹,也可以给整个页面添加边框或底纹,我简单的设置了一下,先看看效果怎么样,别说我设置的难看哦。1、点边框和底纹按钮,找到边框和底纹,点开&#xff…

i++与i=i+1 一样吗可以互换吗

原文链接:https://zhidao.baidu.com/question/84652577.html?qblrelate_question_6&wordshort%20i%20%3D%201%3B%20i%20%3D%20i%201%B6%D4%C2%F0%2Cshort%20i%20%3D%201%3B%20i%20%3D%201%3B%B6%D4%C2%F0 在讲bai课时老师会说“i是ii1的简略du形式”。不过很遗…