我收到了ConcurrentModificationException
,我不知道如何修复它。
我有一个Android多线程应用程序(与套接字通信),我将回调(接口)存储到一个hashmap中。
public class ApiManager {
private static ApiManager instance;
public synchronized ApiManager getInstance() {
if (instance == null)
instance = new ApiManager();
return instance;
}
private final HashMap<String, Callback> callbacks = new HashMap<>;
// Setters and getters for storing callbacks
private @Nullable Callback getCallback(@NoNull String key) {
synchronized (callbacks) {
return callbacks.get(key);
}
}
private void addCallback(@NonNull String key, @NonNull Callback callback) {
synchronized (callbacks) {
callbacks.put(key, callback);
}
}
private void removeCallback(@NonNull String key) {
synchronized (callbacks) {
callbacks.remove(key);
}
}
// Request to retrieve the user's profile from server
public synchronized void getProfile(String key, Callback callback) {
// Save the callback
addCallback(key, callback);
// Do the asynchronous request
getSocket().emit("getProfile", new Ack() {
@Override
public void call(Object... args) {
// Deliver the response
Callback callback = getCallback(key);
if (callback != null)
callback.onResponse(args);
// Remove the callback
removeCallback(key);
}
});
}
// Called when the socket disconnects
// ----> This is the method where I get the exception !
private void onSocketDisconnect() {
/*
* Notify stored callbacks that the socket has disconnected
*/
synchronized (callbacks) {
Set<Map.Entry<String, Callback>> set = callbacks.entrySet();
if (set.size() > 0) {
Iterator<Map.Entry<String, Callback>> iterator = set.iterator();
while (iterator.hasNext()) {
// This is the line where the exception occurres
Map.Entry<String, Callback> entry = iterator.next();
String key = entry.getKey();
Callback callback = entry.getValue();
if (callback != null) {
// Notify callback that there was a socket disconnect exception
callback.onResponse(Factory.buildResponseFailure(SOCKET_DISC));
it.remove();
}
}
}
}
}
}
有时会发生异常:
Exception: java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:851)
at java.util.HashMap$EntryIterator.next(HashMap.java:891)
at java.util.HashMap$EntryIterator.next(HashMap.java:890)
这是我检索用户个人资料的方式:
ApiManager.getInstance().getProfile(KEY_PROFILE_REQ, new Callback() {
@Override
public void onResponse(Object... args) {
// Parsing the data
}
});
正如您所看到的,我正在访问synchronized
块中的hashmap。 ApiManager
类是单身。如果我在迭代时锁定对象,为什么我会得到ConcurrentModificationException
?其他线程如何获得锁定?我错过了什么吗?
注意:在这个例子中是3个线程。 UI线程(我称之为getProfile()
方法),第二个线程是套接字的内部线程(传递响应),另一个线程调用onSocketDisconnected()
方法。
答案 0 :(得分:0)
在迭代过程中从集合中删除项目可能会导致此问题。您是否尝试过存储要删除的项目,然后在处理完最终元素后,set.removeAll(某处)?