Android ConcurrentModificationException 集上

标签: Java Android
发布时间: 2017/3/19 14:07:32
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我读过很多关于这一问题的等问题,但我不能理解为什么有java.util.ConcurrentModificationException

我有这一类︰

private Set<RequestOrders> mRequests = new HashSet<>();
private final Object lock = new Object();

上的所有操作 mRequest 对象被包围这样的同步语句︰

public void handleOrder(RequestOrders order) {
    synchronized (lock) {
        if (!mRequests.contains(order)) {
            final sOrder = saveOrderOnDB(order);
            mRequests.add(sOrder);

            handleOrder(sOrder;
        }
    }
}

我在这得到的错误︰

void notifyOrder(int type) {
    if (!mPause) {
        synchronized (lock) {
            for (RequestOrders request : mRequests) { // Error here while iterating
                if (.....) {
                    redirectOrders(request);
                } else if (....) {
                    ......
                    startService(.....);
                }
            }
        }
    } else {
        .....
    }
}

不知道为什么?不应该同步的语句防止并发问题吗?

解决方法 1:

它看起来像你的方法调用来添加 / 删除 RequestOrders 从集可能发生而你仍然遍历 mRequest 套。因此 mRequest 集的大小更改时你仍循环而导致错误。为了克服这个问题,您可以执行︰

1-创建一套临时保存所有对象添加到 mRequest。一旦你完成遍历 mRequest 组中的所有对象,在临时设置到 mRequest 集添加的所有对象。

2-使用并发的 HashMap。

这里是如何您可以使用第一种方法的一个示例︰

private Set<RequestOrders> mRequests = new HashSet<>();
private Set<RequestOrders> backlog = new HashSet<>();

public void handleOrder(RequestOrders order) {
    synchronized (lock) {
        if (!mRequests.contains(order)) {
            final sOrder = saveOrderOnDB(order);
            backlog.add(sOrder);
            handleOrder(sOrder);
        }
    }
}

void notifyOrder(int type) {
    if (!mPause) {
        for (RequestOrders request : mRequests) { // Error here while iterating
            if (.....) {
                redirectOrders(request);
            } else if (....) {
                ......
                startService(.....);
            }
        }
        mRequests.addAll(backlog);
        backlog.clear();
    } else {
        .....
    }
}
官方微信
官方QQ群
31647020