我必须从存储中迭代的列表中删除该元素。即使使用Iterator,它也会引发ConcurrentModificationException。该代码将在活动结束时执行。请参阅:iter1.remove()。请建议是否有任何解决方法。
List<OfflineCommand> l_loc = (List<OfflineCommand>) Storage.getInstance().readObject("LocationTest");
if (l_loc != null) {
boolean flgSuccess = true;
ListIterator<OfflineCommand> iter1 = l_loc.listIterator();
while (iter1.hasNext()) {
OfflineCommand oc = iter1.next();
flgSuccess = executeOfflineCommand(oc);
if (!flgSuccess) {
break;
} else {
iter1.remove();
}
}
}
在另一个地方,我使用下面的代码每分钟将条目添加到同一列表中。
List<OfflineCommand> l_noAppt = Storage.getInstance().readObject("LocationTest");
if (l_noAppt == null) {
l_noAppt = new ArrayList<>();
}
l_noAppt.add(new OfflineCommand(name, args));
Storage.getInstance().writeObject("LocationTest", l_noAppt);
答案 0 :(得分:1)
在一个位置上添加元素同时在另一个位置上删除需要同步。
A)使用 Vector 。
Vector提供了开箱即用的同步功能。但是即使对于Vector,也不要使用Iterator ,因为您有并发的修改。
// On the place where you create your list now, create a Vector,
// like ... = new Vector<...>() instead of ... = new ArrayList<...>().
// Just a cast is not sufficient of course.
Vector<OfflineCommand> l_loc = ...;
if (l_loc != null) {
boolean flgSuccess = true;
while (!l_loc.isEmpty()) {
OfflineCommand oc = l_loc.get(0);
flgSuccess = executeOfflineCommand(oc);
if (!flgSuccess) {
break;
} else {
l_loc.remove(0);
}
}
}
优点:您不需要显式同步。您的代码保持紧凑。
B)使用显式同步。
List<OfflineCommand> l_loc = ...;
if (l_loc != null) {
boolean flgSuccess = true;
while (!l_loc.isEmpty()) {
OfflineCommand oc = l_loc.get(0);
flgSuccess = executeOfflineCommand(oc);
if (!flgSuccess) {
break;
} else {
synchronized (l_loc) {
l_loc.remove(0);
}
}
}
}
重要提示:在将对象添加到此列表的位置上,还应该使用同步:
synchronized(l_loc) {
l_loc.add(...);
}
第二种方法不是那么可靠,因为您应该牢记可以修改列表的所有位置,并在那里使用同步。
A和B这两种方法都可以解决并发修改问题。
答案 1 :(得分:0)
您的问题含糊。 为了避免ConcurrentModificationException,请使用ConcurrentHashMap并使用FOR循环。
答案 2 :(得分:-1)
一旦调用remove()
,Iterator
实例将变为无效。有几种解决方法。由于您删除了所有元素,直到输入不成功为止,类似iter1 = l_loc.listIterator();
或在上下文中这样的工作正常:
while (iter1.hasNext()) {
OfflineCommand oc = iter1.next();
flgSuccess = executeOfflineCommand(oc);
if (!flgSuccess) {
break;
} else {
iter1.remove();
iter1 = l_loc.listIterator();
}
}