ConcurrentModificationException,但我并没有修改我正在迭代的集合。

huangapple go评论77阅读模式
英文:

ConcurrentModificationException but I am not modifying the Collection I am iterating

问题

我正在迭代一个消息对象列表试图获取所有会话其中会话表示在上一条消息之后的 20 分钟内发送了后续消息

第一次迭代运行正常在第二次迭代中我遇到了 **java.util.ConcurrentModificationException** 异常
尽管我没有修改我正在迭代的消息列表请参阅下面的代码

public List<Chat> getAllConversations(int allowedMinutes) {
    List<Chat> result = new ArrayList<>();
    Chat currentConvo = new Chat();
    List<Message> ml = this.getMessageList();
    for (Message m : ml) {
        if (currentConvo.getMessageList().isEmpty() || m.getDateTime().until(currentConvo.getMessageList().get(currentConvo.getMessageList().size() - 1).getDateTime(), ChronoUnit.MINUTES) <= allowedMinutes) {
            currentConvo.addMessage(m);
            continue;
        }
        if (currentConvo.getAllParticipants().size() > 1) {
            // only if more than one participant is involved it is a conversation
            result.add(currentConvo);
        }
        // not more than one person involved and also last message is too long ago -> discard the current conversation
        currentConvo = new Chat();
        currentConvo.addMessage(m);
    }
    return result;
}

这是错误消息

D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chatstats, PID: 22185
java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.next(ArrayList.java:860)
    at com.example.chatstats.Chat.getAllConversations(Chat.java:188)
    at com.example.chatstats.MainActivity.onClickShowResults(MainActivity.java:169)
    at com.example.chatstats.MainActivity$9.onClick(MainActivity.java:152)
    at android.view.View.performClick(View.java:6256)
    at android.view.View$PerformClick.run(View.java:24701)
    at android.os.Handler.handleCallback(Handler.java:789)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
I/zygote: WaitForGcToComplete blocked for 14.815ms for cause HeapTrim
Disconnected from the target VM, address: 'localhost:8622', transport: 
'socket'

感谢您的回复
英文:

I am iterating over a list of Message objects with the attempt to get all conversations, where conversation means that a subsequent message was sent within 20 Minutes after the previous message.

The first iteration works fine, and in the second one I am getting a java.util.ConcurrentModificationException
Even though I am not modifying the Message List I am iterating. See code below.

public List&lt;Chat&gt; getAllConversations(int allowedMinutes) {
List&lt;Chat&gt; result = new ArrayList&lt;&gt;();
Chat currentConvo = new Chat();
List&lt;Message&gt; ml = this.getMessageList();
for (Message m : ml) {
if (currentConvo.getMessageList().isEmpty() || m.getDateTime().until(currentConvo.getMessageList().get(currentConvo.getMessageList().size() - 1).getDateTime(), ChronoUnit.MINUTES) &lt;= allowedMinutes) {
currentConvo.addMessage(m);
continue;
}
if (currentConvo.getAllParticipants().size() &gt; 1) {
// only if more than one participant is involved it is a conversation
result.add(currentConvo);
}
// not more than one person involved and also last message is too long ago -&gt; discard the current conversation
currentConvo = new Chat();
currentConvo.addMessage(m);
}
return result;
}

This is the Error Message:

D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chatstats, PID: 22185
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at com.example.chatstats.Chat.getAllConversations(Chat.java:188)
at com.example.chatstats.MainActivity.onClickShowResults(MainActivity.java:169)
at com.example.chatstats.MainActivity$9.onClick(MainActivity.java:152)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
I/zygote: WaitForGcToComplete blocked for 14.815ms for cause HeapTrim
Disconnected from the target VM, address: &#39;localhost:8622&#39;, transport: 
&#39;socket&#39;

Thank you for your replies.

答案1

得分: 2

但是你在例外情况下并没有撒谎。有可能是另一个线程在执行这个操作;更有可能的情况是你的for循环中的某行代码引起了变动。例如,也许addMessage命令会确定消息已经属于哪个聊天,并将其从那个聊天中移除 - 也就是从你这边移除,改变了列表。

编辑:正如Andreas所评论的,另一个可能的解释是你错误地将messageList字段设为了static。在这种情况下,所有不同的聊天对象共享一个列表,因此,向新创建的聊天对象添加消息仍然会将其添加到单一的全局列表中。解决办法是:将其设为非静态。

英文:

But you are; the exception is not lying to you. It is possible another thread is doing it; it is more likely one of the lines in your forloop is causing a change. For example, perhaps the addMessage command figures out which Chat the message is already a part of, and removes it from there – i.e. from you, changing the list.

EDIT: As Andreas has commented, another plausible explanation is that you've accidentally made the messageList field static. In that case, all the different chat objects share a single list, and thus, adding a message to a newly created Chat object is still adding it to the single global list. Solution if this is the case: Make it non-static.

huangapple
  • 本文由 发表于 2020年3月4日 05:53:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/60516075.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定