我已经阅读了许多有关此问题的SO问题,但我无法理解为什么我会遇到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 {
.....
}
}
知道为什么吗?同步语句不应该防止并发问题吗?
最佳答案
看起来,当您仍在迭代 mRequest 集时,可能会发生从集合中添加/删除 RequestOrders 的方法调用。因此,当您仍在迭代时,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 {
.....
}
}
关于java - Android Set 上的 ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40676739/