Android——数组访问的同步问题

来源:互联网 发布:ubuntu重新安装lamp 编辑:程序博客网 时间:2024/05/18 21:50

今天将上次写的那个View改进了一下,让它能够自动生成新的球,在球多次碰撞后会自动消失掉,在消失的地方会留下一圈波浪形的圆圈痕迹。

本来应该是很简单的东西,但在实现的过程中却遇到了一些问题,程序崩溃了N多次。

在程序中使用两个线程来进行管理,一个线程负责画面的更新,另一个线程负责新的球的生成。因为这两个线程都会访问到同一个数组,并且有一个线程可能会将这个数组中的一些元素删除,这时候就遇到了数据的同步问题。当一个线程要删除另一个线程正在读取的元素时,程序就会崩溃,显示的错误是 ConcurrentModificationException。 

经过上网查找,发现解决问题的一种办法是用同步锁将对象给锁住,在这段代码完全结束前,其它代码不能对这段代码进行操作。但我加了同步锁之后,这个Exception还是继续会出现。然后我几乎把所有的代码都加上了同步锁,仍然会抛出错误(同步锁对系统资源的消耗极大,所以一般不会加上同步锁,这次使用它只是为了排除错误)。

在多次测试没有效果后,我又重新看了一遍Logcat,发现了这一句在Exception的下面还有两句话(不会截图……)

at java.util.LinkedList$LinkIterator.next(LinkedList java:124)

at com.elfman.MyView.TheScreen.onDraw( Main.java:163)

看得出这个错误是因为迭代器不能访问到了下一个数组的元素,从而引起错误。但我并没有使用迭代器啊!

在Main文件里找到了第163行对应的代码,为 for( Circle circle : circles ),应该是在这种句式中系统就会调用了迭代器吧(这个句式不怎么用过,只是在网上看到别人介绍几种获取数组元素的方法,说这种方法最高效,但没想到这个会很容易出问题,然后我的另一个线程将其中一个元素删除后,迭代器就失灵了,导致程序崩溃。

改正方法:将这句代码改为for(int i=0; i<circles.size(); i++ ),然后再把其它几处也使用这种句式的代码改正过来,再次运行,连续运行了十几分钟,没有再崩溃,程序成功。再将几个同步锁去掉,也没有再出问题。

现在的程序已经可以很好地运行了,感觉还不错,过两天再往这个程序里加上一些互动的元素,就可以做成一个小游戏了,嘿嘿!!

贴上代码: