以下代碼由線程池執行。首先,Map不是併發的,所以我改變了這一點,但我仍然在第二行發現修改異常。 爲了將這段代碼變成線程安全的,我應該做些什麼改變?映射併發 - 修改異常
ConcurrentHashMap<String, Account> entriesOnFile = IniReaderHelper.load();
for (Map.Entry<String,Account> entryFromFile: entriesOnFile.entrySet())
{
EntryWrapper wrapperFromEntriesFile = new EntryWrapper(entryFromFile.getValue());
if (wrapperFromEntriesFile.getName().equals(entryName))
{
Tracer.info("Found matching entry from the entries file for +'" + entryName + "'");
synchronized(this)
{
context.put(RequestServices.ENTRY_WRAPPER, wrapperFromEntriesFile);
}
entry = wrapperFromEntriesFile;
break;
}
}
一些更多信息: 下面是返回地圖的.load()函數的代碼:
static public ConcurrentHashMap<String, Account> load() throws Exception
{
BufferedReader reader = null;
accounts.clear();
try
{
reader = new BufferedReader(new FileReader(getEntriesFile()));
Account current = null;
String accountName;
String line;
while ((line = reader.readLine()) != null)
{
... do stuff here then adding entry to the amp
accounts.put(accountName, current);
}
}
finally
{
if (reader != null)
reader.close();
}
return accounts;
}
這裏是堆棧跟蹤:
error code [1] : 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 .....call(AsyncCommand.java:78)
堆棧跟蹤指向第二行('for'循環)並寫入「EntryIterator.next」,因此這不意味着我應該更改:
for (Map.Entry<String,Account> entryFromFile: entriesOnFile.entrySet())
到
for (ConcurrentHashMap.Entry<String,Account> entryFromFile: entriesOnFile.entrySet())
這裏是「賬戶」
private static ConcurrentHashMap<String, Account> accounts = new ConcurrentHashMap<String, Account>();
發佈stacktrace。 – Jukka
它看起來並不像你正在修改entriesOnFile Map,所以你要麼沒有向我們展示代碼,要麼你沒有告訴我們你的異常是什麼。 – Deadron
我不想修改地圖。我從文件中讀取了一些類型爲Account的條目into entriesOnFile。然後,我瀏覽地圖中的每個條目,並將其名稱與entryName進行比較,如果匹配,我會執行一些操作。我得到的例外是修改,並在第二行,其中「for」是。我從我的一位客戶那裏得到了日誌,因爲這部分代碼在極端情況下運行,所以我實際上無法在實驗室中重新創建這些日誌。 – WhiteLady