0

以下のコードは、スレッド プールによって実行されます。まず、マップは並行していなかったので変更しましたが、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>();
4

2 に答える 2

0

私が見る限り、スレッド間でアカウント マップを共有することは意味がありません (load() を呼び出すたびにマップをクリアして再構築するため、最も簡単な修正は、共有された静的マップ (アカウント) を削除してロードすることです)。 () 呼び出しごとに新しい Map を作成して返します。

于 2013-06-13T06:06:59.407 に答える