以下のコードは、スレッド プールによって実行されます。まず、マップは並行していなかったので変更しましたが、2 行目で変更例外が発生します。このコードをスレッドセーフにするには、どのような変更を行う必要がありますか?
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)
スタック トレースは 2 行目 (「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>();