HashMapの同時問題


前のコード
public class CurrMap {

    /**   */

    private static final Executor EXECUTOR = Executors.newFixedThreadPool(20);

    /**
     * 
     * @param args
     */
    public static void main(String[] args) {

        //      final  Map<String, String> map = new ConcurrentHashMap<String, String>();
        final Map<String, String> map = new HashMap<String, String>();
        map.put("laotu", "handsome");
        final Random random = new Random();

        while (true) {

            EXECUTOR.execute(new Runnable() {
                public void run() {

                    for (int i = 0; i < 1000; i++) {
                        try {
                            TimeUnit.MILLISECONDS.sleep(1);
                        } catch (InterruptedException ex) {
                            System.err.println("t5 catch the InterruptedException...");
                        }
                        for (String key : map.keySet()) {
                        }
                    }

                }
            });

            for (int i = 0; i < 100; i++) {

                EXECUTOR.execute(new Runnable() {

                    public void run() {

                        for (int i = 0; i < 1000; i++) {
                            try {
                                TimeUnit.MILLISECONDS.sleep(1);
                            } catch (InterruptedException ex) {
                                System.err.println("t1 catch the InterruptedException...");
                            }
                            int key = random.nextInt(1000);
                            map.put(String.valueOf(key), String.valueOf(key));
                        }
                    }

                });

            }
        }

    }

}

実行結果:
Exception in thread "pool-1-thread-1" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
	at java.util.HashMap$KeyIterator.next(HashMap.java:828)
	at com.alipay.ctu.biz.intl.filters.CurrMap$1.run(CurrMap.java:52)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
	at java.lang.Thread.run(Thread.java:695)

次の2つのシナリオを試します.
a.HashMapをConcurrentHashMapに交換して実行する.
b.HashMapを使用する、第1セグメントEXECUTORを注釈する.executeのコードを実行します.
結果は次のとおりです.
案aは間違いを報告しないに違いない.シナリオbはこの間違いを報告しないはずだが、この間違いを報告する可能性は極めて小さい.
適用シーン:
取引の支払いイベントが来て、イベントのタイプはHashMapで、私達はカードの情報、IP情報などに対して情報の補完を行う必要があって、スレッドプールを通じて同時に情報の補完を実行する過程の中で、各スレッドの内部でmapを実行しました.put(key,value)の操作により、高同時で異常javaが投げ出す可能性がある.util.ConcurrentModificationException.(出現確率が低い)
このときスレッドでmapが実行する場合.keySet()操作、map中のデータを遍歴すると、異常javaが発生する.util.ConcurrentModificationExceptionの確率が高いです.
HashMapを使用すると、スレッドが安全ではないことがわかりますが、どのような問題が発生する可能性がありますか?
a.putのデータが失われた.
b.removeのデータは消去されず、依然として存在する.
c.HashMap resizeによるパフォーマンスの問題.
d.getデータの場合、デッドサイクルが発生します.
ソリューション:
ConcurrentHashMapがおすすめです.
では、何が原因なのでしょうか.
以下の2つの文章を参照することができる
http://www.iteye.com/topic/656670 http://www.iteye.com/topic/962172