嗨,我正在運行一個線程服務,此線程的任務是檢查HashMap
中的列表項的年齡。當一件物品比5秒鐘還舊時,我將不得不從HashMap
中刪除物品。以下是簡化代碼。但是,當代碼嘗試從HashMap中刪除項目時,我得到java.util.ConcurrentModificationException
。在修改線程類中的HashMap時獲取ConcurrentModificationException
我在原始程序中的main()
方法中填充了HashMap
。 有人可以幫我解決這個問題嗎?
PS:deleteFromTrackList()
由不同的客戶端通過RMI通過網絡進行調用。
import java.util.*;
public class NotifierThread extends Thread {
private HashMap<Integer, ArrayList> NotificationTrackList = new HashMap<Integer, ArrayList>();
@Override
public void run() {
while (true) { // this process should run continuously
checkNotifierList(getNotificationTrackList());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public HashMap<Integer, ArrayList> getNotificationTrackList() {
return NotificationTrackList;
}
public void deleteFromTrackList(Integer messageID) {
NotificationTrackList.remove(messageID);
}
public synchronized void checkNotifierList(HashMap list) {
Set entries = list.entrySet();
for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
Map.Entry<Integer, ArrayList> entry = (Map.Entry) iterator.next();
ArrayList messageInfo = entry.getValue();
Integer messageID = entry.getKey();
messageInfo = new ArrayList((ArrayList) list.get(messageID));
Long curTime = new Date().getTime();
Long refTime = (Long) messageInfo.get(1);
Long timeDiff = curTime - refTime;
if (timeDiff > 5000) {
// delete the entry if its older than 5 milliseconds and update
// internal entry list
deleteFromTrackList(messageID);
}
}
}
public static void main(String[] args) {
new NotifierThread().start();
}
}
這是我在控制檯
Exception in thread "tracker" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$EntryIterator.next(Unknown Source)
at java.util.HashMap$EntryIterator.next(Unknown Source)
at NotifierThread.checkNotifierList(NotifierThread.java:32)
at NotifierThread.run(NotifierThread.java:10)
我試過'iterator.remove();'但我需要刪除循環以外的項目,因爲'deleteFromTrackList(messageID);'由不同的客戶端通過RMI跨網絡調用。 – Rakesh
事實上,您需要有一個單獨的方法來使其他客戶端能夠刪除消息ID,但這並不妨礙您在迭代時刪除迭代器時使用iterator.remove。在迭代列表時,您應該確保沒有其他線程調用deleteFromTrackList。不要讓地圖逃離班級,並同步每個地圖的訪問權限。 –