java - 为什么即使同步了列表也会出现ConcurrentModificationException?

标签 java concurrentmodification

我有 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/

相关文章:

java - 在 Android 操作系统上捕获未处理的 JAVA 运行时异常的最佳实践?

java - 打印 vector 内容时出现 ConcurrentModificationException

java - 如何在 freemarker 中将日期转换为字符串?

java - 当我迭代 ArrayList 时出现 ConcurrentModificationException

java - 关于Java ServerSocket接受: busy-wating?

java - 记录 0x5B 的初始化留下 1 个字节仍待读取。 Apache POI Java

java - 如何迭代 Collection<T> 并修改其项目而不出现 ConcurrentModificationException?

java - 使用迭代器和 iterator.remove() 时出现 ConcurrentModificationException

java - 如何修复流关闭异常

java - Animation 方法中出现 NullPointerException 问题