zoukankan      html  css  js  c++  java
  • 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一个不可变的参数才能保证其原子性

  • 相关阅读:
    网络流之对偶图转最短路
    BZOJ5418 NOI2018屠龙勇士EXCRT
    BZOJ1951 [Sdoi2010]古代猪文 NOIP数论大杂烩
    中国剩余定理及EX及单层EXLucas定理讲解
    网络流24题之负载平衡问题
    输入一个url到浏览器页面展示都经历了哪些过程
    前端部署dist包到服务器
    img标签显示 base64格式的 图片
    字符串用react 用sha256加密
    前端下载证书文件cer用后端返回的加密数据
  • 原文地址:https://www.cnblogs.com/sprinng/p/6627713.html
Copyright © 2011-2022 走看看