我有一个OpenGL ES 2.0应用程序。内它,我有一个包含像这样另一类型的对象的一个阵列(这被简化为问题)的类:Java:保护一个对象不被多线程访问
public class StoreList(){
thisList StoreItems[];
public StoreList(int nuberOfItems){
thisList = StoreItems[numberOfItems];
}
}
最初,我该应用中填充列表,然后在某些点(当用户在“存储”场景),它可能被添加到列表中的新项目,因此,举例来说,这个名单可以是这个样子:现在
Before After inserting object 'Fish' into index 1
Index 0 - Dog Index 0 - Dog
Index 1 - Fox Index 1 - Fish
Index 2 - Bird Index 2 - Fox
Index 3 - Snake Index 3 - Bird
Index 4 - Snake
,这个名单是通过迭代出于各种原因。例如,用于渲染,更新它们的位置等。
我遇到的问题是,我的应用程序使用2个线程 - GL渲染线程和Main/UI线程。
当用户执行某个动作时,UI线程调用插入额外项目的'insertObject'方法,如上所述。然而,渲染线程很乐意做它的事情,如果它是在索引1处同时渲染对象'insertObject'被调用,那么它开始导致问题(列表中的每个对象具有不同数量的openGL四边形来绘制并且绘制的数字包含在对象本身的一个变量中),所以如果索引1处的原始对象有5个四边形,并且新对象只有4个,那么它开始尝试绘制第五个四边形,并且我们得到所有问题的方式(索引超出范围)。
render方法,updateLogic方法和onTouchEvent方法都被声明为synchronized,但我仍然遇到这个问题。
我不确定如何去确保这个对象(StoreList的实例及其中的所有内容,它是'thisList'数组)只能从一个线程一次更新。
我看到的有关并发问题的问题都是关于保护一个方法不被多线程而不是对象调用,所以我有点困惑。
希望得到任何指导。
也许一个['CopyOnWriteArrayList'](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html)会更适合你吗? – RealSkeptic
最简单的方法:通过['Lock'](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.html)保护列表。每个想要读取或写入列表的方法都需要首先获取“Lock”。稍微复杂一些:尝试使用['@ synchronized'](https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html)。只要'@ synchronized'内没有使用阻塞结构(比如'wait()'),就可以完成这项工作。 – Turing85
Thanks @ Turing85,你的意思是在所有将从列表中读/写的代码上使用同步块? (使用列表本身作为锁定对象?)我只是想知道我是否可以简单地声明任何读取/写入列表的同步方法?我刚刚那样做,迄今没有崩溃(经过大约30次测试)。我也不确定你的意思是'@synchronized'。你能提供一个例子吗?谢谢你的帮助。 – Zippy