我有 Android 多线程应用程序。
两个或多个触发器可能会运行同一部分代码。
我有一个对象列表。
我让它被 Collections.synchronizedList
同步
private List<WmGroupItemSample> mGroupItemSampleList;
mGroupItemSampleList = new ArrayList<WmGroupItemSample>();
mGroupItemSampleList = Collections.synchronizedList(mGroupItemSampleList);
但是有时我在线上遇到异常:
Collections.sort(mGroupItemSampleList, new GroupItemSampleComparator());
java.util.ConcurrentModificationException
at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:62)
at java.util.Collections.sort(Collections.java:1895)
- 这个流程合法吗?
- 我是否需要创建副本并对副本运行排序?
- 为什么
Collections.synchronizedList
不能阻止这个异常?
[编辑]
GroupItemSampleComparator
public class GroupItemSampleComparator implements java.util.Comparator<WmGroupItemSample> {
public GroupItemSampleComparator() {
super();
}
public int compare(WmGroupItemSample s1, WmGroupItemSample s2) {
return ( (s2.getStartDate() - s1.getStartDate()) > 0 ) ? (-1) : (1);
}
}
谢谢,
最佳答案
基本问题是同步列表没有以有用的方式同步。
问题在于,虽然它的方法是同步的,但像移动元素这样应该是原子的操作却不是,因为移动所需的单独调用没有同步在一起。这意味着其他线程可以进入各个方法调用之间。因此,同步集合现在已基本弃用。
尽管有这个缺陷,如果您有另一个线程在您的线程排序时添加一个元素,您将得到这个异常,因为排序迭代并且在迭代期间更改列表会导致异常。
幸运的是,JDK 有新的 Collection 类,它们具有工业强度(和有用的)同步,由 java.util.concurrent
包提供。
用 CopyOnWriteArrayList
替换您的列表,不要“同步”它,你会很高兴。
关于java - 为什么即使同步了列表也会出现ConcurrentModificationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25113987/