mpe*_*egr 5 java multithreading synchronized linkedhashmap concurrentmodification
我在我的类中使用了一个Map对象,我已经与LinkedHashMap的Collections.synchronizedMap()同步,如下所示:
private GameObjectManager(){
gameObjects = Collections.synchronizedMap(new LinkedHashMap<String, GameObject>());
}
Run Code Online (Sandbox Code Playgroud)
我在这个函数的第三行得到一个并发修改异常:
public static void frameElapsed(float msElapsed){
if(!INSTANCE.gameObjects.isEmpty()){
synchronized(INSTANCE.gameObjects){
for(GameObject object : INSTANCE.gameObjects.values()){...}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在迭代Map的所有其他位置,我按照文档同步地图.
我的类中还有其他函数使用这个Map(同步的!)和put()和remove()对象,但这应该无关紧要.我究竟做错了什么?请询问更多代码,不知道还能提供什么.
哦,和日志消息:
08-20 15:55:30.109: E/AndroidRuntime(14482): FATAL EXCEPTION: GLThread 1748
08-20 15:55:30.109: E/AndroidRuntime(14482): java.util.ConcurrentModificationException
08-20 15:55:30.109: E/AndroidRuntime(14482): at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:350)
08-20 15:55:30.109: E/AndroidRuntime(14482): at java.util.LinkedHashMap$ValueIterator.next(LinkedHashMap.java:374)
08-20 15:55:30.109: E/AndroidRuntime(14482): at package.GameObjectManager.frameElapsed(GameObjectManager.java:247)
08-20 15:55:30.109: E/AndroidRuntime(14482): at package.GamekitInterface.render(Native Method)
08-20 15:55:30.109: E/AndroidRuntime(14482): at package.GamekitInterface.renderFrame(GamekitInterface.java:332)
08-20 15:55:30.109: E/AndroidRuntime(14482): at com.qualcomm.QCARSamples.ImageTargets.GameEngineInterface.onDrawFrame(GameEngineInterface.java:107)
08-20 15:55:30.109: E/AndroidRuntime(14482): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
08-20 15:55:30.109: E/AndroidRuntime(14482): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
Run Code Online (Sandbox Code Playgroud)
ysh*_*vit 12
尽管名称如此,但这与多线程意义上的并发性无关.除非通过调用remove()迭代器,否则在迭代时不能修改此映射.也就是说,你有......
for(GameObject object : INSTANCE.gameObjects.values()){...}
Run Code Online (Sandbox Code Playgroud)
如果...修改INSTANCE.gameObjects.values()(例如,删除或添加元素),next()迭代器上的下一次调用(对for循环是隐式的)将抛出该异常.
大多数集合和Map实现都是如此.javadoc通常指定该行为,但并不总是显而易见.
修正:
如果您要执行的操作是删除元素,则需要显式获取Iterator<GameObject>并调用remove()它.
for (Iterator<GameObject> iter = INSTANCE.getObjects().values(); iter.hasNext(); ;) {
GameObject object = iter.next();
if (someCondition(object)) {
iter.remove();
}
}
Run Code Online (Sandbox Code Playgroud)putAll(temporaryMapForAdding).| 归档时间: |
|
| 查看次数: |
3282 次 |
| 最近记录: |