简体   繁体   English

有时会收到java.util.ConcurrentModificationException,有时则不会。 不知道为什么

[英]Sometimes receiving java.util.ConcurrentModificationException, sometimes not. Can't figure out why

So firstly here are the error messages: 因此,首先是错误消息:

Exception in thread "Thread-2" 线程“ Thread-2”中的异常
java.util.ConcurrentModificationException java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source) 在java.util.ArrayList $ Itr.checkForComodification中(未知源)
at java.util.ArrayList$Itr.next(Unknown Source) 在java.util.ArrayList $ Itr.next(未知源)
at zom.mainpac.Game.render(Game.java:218) 在zom.mainpac.Game.render(Game.java:218)
at zom.mainpac.Game.run(Game.java:154) 在zom.mainpac.Game.run(Game.java:154)
at java.lang.Thread.run(Unknown Source) 在java.lang.Thread.run(未知来源)

Rendering my ArrayList of Objects at Line 218: 在第218行呈现我的ArrayList对象:

    for(Objects e : list){
    e.render(g);
    }

And then my render function at line 154: 然后我的渲染功能在第154行:

    render();

... ...

private void render() {

    BufferStrategy bufferStrategy = this.getBufferStrategy();

    if (bufferStrategy == null) {

        this.createBufferStrategy(2);
        return;

    }

The problem is probably because my laptop cant render all of the Objects SOMETIMES , so it gives up. 这个问题可能是因为我的笔记本电脑不能使所有的对象有时 ,所以放弃了。 So im just wondering if there is a better way I can do this without it crashing all the time. 所以我只是想知道是否有更好的方法可以做到这一点而不会一直崩溃。

You have a thread safety issue and/or list access issue. 您遇到线程安全问题和/或列表访问问题。 You may want to copy the list/array items into a local variable so your list cannot be modified while you traverse and/or consider synchronization block. 您可能希望将列表/数组项复制到局部变量中,以便在遍历和/或考虑同步块时无法修改列表。

Your instance list variable is being accessed by one thread (performing the for loop) and then another thread comes along and maybe it wants to access it. 一个线程正在访问您的实例列表变量(执行for循环),然后另一个线程出现,也许它想访问它。 To solve instead of performing a for loop using the instance variable create a local variable and copy the items from the .list. 若要解决而不是使用实例变量执行for循环,请创建一个局部变量,然后从.list复制这些项目。 now you have a private list that no other thread can access 现在您有一个私有列表,其他任何线程都无法访问

The problems happens because your code modifies the list while iterating. 发生问题是因为您的代码在迭代时修改了列表。

  • If you have only one thread which reads/writes from/to the list, then the most likely the call 如果只有一个线程可以从列表中读取/写入列表,则最有可能调用

    this.createBufferStrategy(2); this.createBufferStrategy(2);

sometimes adds some elements to the same array list. 有时会将某些元素添加到同一数组列表中。 You could fix the exception if you will use a copy of the list to iterate: 如果将使用列表的副本进行迭代,则可以解决此异常:

for (Objects e : new ArrayList(list)) {
   e.render(g);
}
  • If you have MORE than one thread to read/write the list, use java.util.concurrent.CopyOnWriteArrayList instead 如果您有多个线程可以读取/写入列表,请改用java.util.concurrent.CopyOnWriteArrayList

The For each uses an iterator to do it's looping, so you're susceptible to such exceptions during iteration if you happen to remove something from that list. For Each使用迭代器进行循环,因此,如果您碰巧要从该列表中删除某些内容,则在迭代过程中很容易遇到此类异常。 This can happen for example if you are removing a tile or sprite from your list in your game while rendering. 例如,如果您在渲染时从游戏列表中删除了图块或精灵,则可能会发生这种情况。 If you are not modifying the List that often you could use a CopyOnWriteArrayList if you wish to modify the List while iterating (let's you not have to create a copy of the list), but it's important to note you should first understand the behavior that causes this and not use a blind fix. 如果您不打算修改列表,那么通常可以使用CopyOnWriteArrayList,如果您希望在迭代时修改列表(那么您不必创建列表的副本),但是请务必注意,首先应该了解导致这并且不要使用盲目修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM