Android HashMap迭代器ConcurrentModificationException
我得到了Android HashMap迭代器ConcurrentModificationException,android,websocket,hashmap,concurrentmodification,Android,Websocket,Hashmap,Concurrentmodification,我得到了ConcurrentModificationException,我不知道如何修复它 我有一个Android多线程应用程序(与套接字通信),我将回调(接口)存储到hashmap中 public class ApiManager { private static ApiManager instance; public synchronized ApiManager getInstance() { if (instance == null) ins
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();
}
}
}
}
}
}
以下是我检索用户配置文件的方式:
ApiManager.getInstance().getProfile(KEY_PROFILE_REQ, new Callback() {
@Override
public void onResponse(Object... args) {
// Parsing the data
}
});
如您所见,我正在synchronized
块中访问hashmap。apimager
类是一个单例。如果在迭代对象时锁定该对象,为什么会得到一个ConcurrentModificationException
?其他线程如何获得锁?我错过什么了吗
注意:本例中有3个线程。UI线程(在这里我调用
getProfile()
方法),第二个线程是套接字的内部线程(传递响应),另一个线程调用onSocketDisconnected()
方法。在对集合进行迭代时从集合中删除项可能会导致此问题。您是否尝试过将要删除的项存储在某个位置,然后在处理完最后一个元素后,设置.removeAll(某处)?在迭代集合时从集合中删除项可能会导致此问题。您是否尝试过将要删除的项存储在某个位置,然后在处理完最后一个元素后,在while(iterator.hasNext())块调用iterator.remove访问数据后在while(iterator.hasNext())块调用iterator.remove访问数据后,在while(iterator.hasNext())块调用iterator.remove。
ApiManager.getInstance().getProfile(KEY_PROFILE_REQ, new Callback() {
@Override
public void onResponse(Object... args) {
// Parsing the data
}
});