我读过很多关于这一问题的等问题,但我不能理解为什么有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 {
.....
}
}
不知道为什么?不应该同步的语句防止并发问题吗?
它看起来像你的方法调用来添加 / 删除 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 {
.....
}
}