• ConcurrentHashMap并不是绝对线程安全的


    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class ConcurrentHashMapDemo1 {
    
        private static Map<Long, Integer> widgetCacheMap = new ConcurrentHashMap<Long, Integer>();
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            for (int i = 0; i < 10000; i++) {
                Thread tt = new Thread(new Rund());
                tt.start();
            }
        }
    
        static class Rund implements Runnable {
    
            public void run() {
                test();
            }
    
            /**
             * 1W次,总有那么几次线程不安全
             */
            public void test() {
                synchronized ("") {// 解决方案
                    ConcurrentHashMapDemo1 tt = new ConcurrentHashMapDemo1();
                    tt.set();
                    int s1 = widgetCacheMap.get(1L).intValue();
                    tt.change();
                    int s2 = widgetCacheMap.get(1L).intValue();
                    if (s1 == s2) {
                        System.out.println(s1 + ":" + s2);
                    }
                }
            }
    
        }
    
        public void set() {
            Map<Long, Integer> mm = new HashMap<Long, Integer>();
            mm.put(1L, 1);
            widgetCacheMap = mm;
        }
    
        public void change() {
            Map<Long, Integer> mm = new HashMap<Long, Integer>();
            mm.put(1L, 2);
            widgetCacheMap = mm;
        }
    
    }
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class ConcurrentHashMapDemo2 {
    
        public static void main(String[] args) throws InterruptedException {
            for (int i = 0; i < 10; i++) {
                System.out.println(test());
            }
        }
    
        private static int test() throws InterruptedException {
            ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
            ExecutorService pool = Executors.newCachedThreadPool();
            for (int i = 0; i < 8; i++) {
                pool.execute(new MyTask(map));
            }
            pool.shutdown();
            pool.awaitTermination(1, TimeUnit.DAYS);
    
            return map.get(MyTask.KEY);
        }
    }
    
    class MyTask implements Runnable {
    
        public static Object lock = new Object();
    
        public static final String KEY = "key";
    
        private ConcurrentHashMap<String, Integer> map;
    
        public MyTask(ConcurrentHashMap<String, Integer> map) {
            this.map = map;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                synchronized (lock) { // 解决方案
                    this.addup();
                }
            }
        }
    
        private void addup() {
            if (!map.containsKey(KEY)) {
                map.put(KEY, 1);
            } else {
                map.put(KEY, map.get(KEY) + 1);
            }
        }
    }

    总结:ConcurrentHashMap是线程安全的,那是在他们的内部操作,其外部操作还是需要自己来保证其同步的,特别是静态的ConcurrentHashMap,其有更新和查询的过程,要保证其线程安全,需要syn一个不可变的参数才能保证其原子性

  • 相关阅读:
    RadAsm使用
    如何从外网访问内网
    装SQL server 2008问题解决
    820
    大三学生经验之谈
    ROM与RAM知识
    java mybatis学习一
    java Sprint boot 学习之一
    java读取配置到Hash表里
    数组乱序算法
  • 原文地址:https://www.cnblogs.com/sprinng/p/6627713.html
Copyright © 2020-2023  润新知