我有一种静态方法
在该方法中,有代码的这一部分:
ArrayList<Message> messagesList = new ArrayList<Message>();
if (!clearList) {
messagesList.addAll(messages.getMessagesList());
for (Message msg : messagesList) {
if (msg.getId().length() == 0) {
messagesList.remove(msg);
}
}
}
有时会抛出"并发修改异常",我尝试将该方法声明为"同步",但仍然没有帮助,我无法声明该块同步,因为这是一种静态方法,没有'这个'参考。
如果我需要启动另一个,我也试图停止运行的异步,但这也没有帮助。
帮助赞赏。
这与同步无关。您正在使用迭代器来循环messagesList
,然后在迭代期间使用remove
对其进行修改。您无法做到这一点,因为当迭代期间修改列表时,ArrayList
的迭代器失败。从文档中:
该类的
iterator
返回的迭代器和listIterator
方法是 fafs-fast :如果列表在创建迭代器后的任何时间进行结构修改,则以迭代器自己的remove
或add
方法,迭代器将抛出ConcurrentModificationException
。
您增强的for
循环只是使用Iterator
周围的句法糖,因此您可以显式进行该方法,然后使用迭代器的remove
方法:
Iterator<Message> it = messagesList.iterator();
while (it.hasNext()) {
if (it.next().getId().length == 0) {
it.remove();
}
}
另外,您可以只使用简单的for
向后运行并索引到ArrayList
(因为get(int)
是ArrayList
上的便宜且恒定的时间操作,这对所有List
s并非如此):
int index;
for (index = messagesList.length - 1; index >= 0; --index) {
if (messagesList.get(index).getId().length == 0) {
messagesList.remove(index);
}
}
for (Message msg : messagesList) {
if (msg.getId().length() == 0) {
messagesList.remove(msg);
}
}
在此代码中,您一次使用messagesList
您也将从messagesList
删除数据,这就是为什么您遇到错误并发修改异常 ..
这里更好地解决了您的问题。将所有数据复制到一个阵列列表中以删除&amp;从主列表中删除所有数据。
Message removeMsg = new ArrayList<Message>();
for (Message msg : messagesList) {
if (msg.getId().length() == 0) {
removeMsg.add(msg);
}
}
messagesList.removeAll(removeMsg);
arraylist返回的迭代器是 fail-fast
。
该类的迭代器返回的迭代器和
listIterator
方法是fail-fas
t:如果列表在创建迭代器后的任何时间进行了结构修改,除非通过迭代器自己的删除或添加方法,否ConcurrentModificationException
。因此,面对并发的修改,迭代器会迅速,干净地失败,而不是在未来不确定的时间内冒着任意的,非确定性的行为。
您可以根据迭代器明确而不是隐式调用iterator.remove();
并更改循环。
ArrayList<Message> messagesList = new ArrayList<Message>();
if (!clearList) {
messagesList.addAll(messages.getMessagesList());
for (ListIterator<Message> iterator = messagesList.listIterator();iterator.hasNext();) {
Message message = iterator.next();
if (message.getId().length() == 0) {
iterator.remove();
}
}
}
参考:
- for-each循环
- arraylist java docs
for
循环可能会修改其迭代的列表。这是例外的原因。修改是基于条件的事实是由于列表不一定修改的原因。
使用Iterator
是一种可能的解决方案,它提供了remove()
方法。
您应该为此类使用Synchronize
关键字,因为静态方法不属于任何实例
- 您的问题是不是与同步关联的,但是您所面临的consurrentModification的问题用于保护收集免受收集错误类型的对象。
例如:
防止猫对象进入狗类型的集合。
- 您可以使用Iterator
ArrayList<Message> messagesList = new ArrayList<Message>();
Iterator<Message> itr = messagesList.iterator();
while(itr.hasNext()){
Message m = itr.next();
itr.remove(); // Its remove() method of Iterator NOT ArrayList's
}