私は最近ConcurrentHashMapを使用する必要があるのか、通常のHashMapをマルチスレッド環境で使用できるのかについて私の研究で議論しました。 HashMapsの引数は2です。ConcurrentHashMapより高速です。可能であれば、それを使用する必要があります。そして、ConcurrentModificationException
は、マップ上で反復処理が行われているように見えるので、「マップからPUTしGETすれば、通常のHashMapの問題は何ですか?」議論だった。Javaハッシュマップ - 複数スレッドの投入
同時のPUTアクションまたは同時のPUTとREADが例外につながる可能性があると私は考えていましたので、これを示すテストをまとめました。テストは簡単です。 10個のスレッドを作成します。各スレッドは、同じ1000個のキーと値のペアをマップに繰り返し5秒間書き込んだ後、結果のマップを出力します。
結果は実際には非常に混乱した:
Length:1299
Errors recorded: 0
私は、各キーと値のペアはHashMapの中でユニークだと思ったが、マップを見て、私は同じであり、複数のキーと値のペアを見つけることができます。 何らかの例外や破損したキーや値のいずれかが予想されましたが、私はこれを期待していませんでした。これはどうやって起こるのですか?
ここで私が使用したコードは、参考のために、です:あなたが直面している
public class ConcurrentErrorTest
{
static final long runtime = 5000;
static final AtomicInteger errCount = new AtomicInteger();
static final int count = 10;
public static void main(String[] args) throws InterruptedException
{
List<Thread> threads = new LinkedList<>();
final Map<String, Integer> map = getMap();
for (int i = 0; i < count; i++)
{
Thread t = getThread(map);
threads.add(t);
t.start();
}
for (int i = 0; i < count; i++)
{
threads.get(i).join(runtime + 1000);
}
for (String s : map.keySet())
{
System.out.println(s + " " + map.get(s));
}
System.out.println("Length:" + map.size());
System.out.println("Errors recorded: " + errCount.get());
}
private static Map<String, Integer> getMap()
{
Map<String, Integer> map = new HashMap<>();
return map;
}
private static Map<String, Integer> getConcMap()
{
Map<String, Integer> map = new ConcurrentHashMap<>();
return map;
}
private static Thread getThread(final Map<String, Integer> map)
{
return new Thread(new Runnable() {
@Override
public void run()
{
long start = System.currentTimeMillis();
long now = start;
while (now - start < runtime)
{
try
{
for (int i = 0; i < 1000; i++)
map.put("i=" + i, i);
now = System.currentTimeMillis();
}
catch (Exception e)
{
System.out.println("P - Error occured: " + e.toString());
errCount.incrementAndGet();
}
}
}
});
}
}
あなたのテストでは、 'HashMap'がスレッドセーフではないことが示されました。 – Kayaman
適切な同期なしで複数のスレッドから使用する場合、例外は発生しません。あなたは壊れたデータ構造を持っていますが、不変のままであるという保証はありません。 –
'ConcurrentHashMap'を使用してください。 – Antoniossss