zoukankan      html  css  js  c++  java
  • ConcurrentHashMap 线程不安全

    本文阐述ConcurrentHashMap线程安全问题,ConcurrentHashMap可以保证多线程读写操作时的安全,实际代码使用时,可能会有以下误区,从下面的实例代码中进行演示。

    两个线程分别进行++操作,总共加2000次,核对输出结果是否是2000;

    有误区的实例代码

      实例代码如下所示。

      

    package com.yang.concurrent;
    
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * 错误使用ConcurrentHashMap
     */
    public class ErrorUseConcurrentHashMap implements Runnable {
        private static ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
    
        /**
         * 这种写法会导致多线程情况下value是线程不安全的,和ConcurrentHashMap无关
         */
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                int value = map.get("tom");
                value++;
                map.put("tom", value);
            }
    
        }
    
        public static void main(String[] args) throws InterruptedException {
            map.put("tom", 0);
            ErrorUseConcurrentHashMap errorUseConcurrentHashMap = new ErrorUseConcurrentHashMap();
            Thread thread1 = new Thread(errorUseConcurrentHashMap);
            Thread thread2 = new Thread(errorUseConcurrentHashMap);
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println("最终输出值:" + map.get("tom"));
    
        }
    }
    

      输出结果如下图:

      

    正确的实例代码

      实例代码如下图,我们将上述的代码优化下。使用CAS的操作方式对其进行优化。

      

    package com.yang.concurrent;
    
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * 正确使用ConcurrentHashMap
     */
    public class CorrectUseConcurrentHashMap implements Runnable {
        private static ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
    
        /**
         * 此处我们使用CAS操作方式,来替换Synchronized,提供效率
         */
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                while (true){
                    int oldValue = map.get("tom");
                    int newValue=oldValue+1;
                    boolean flag=map.replace("tom",oldValue,newValue);
                    if (flag){
                        break;
                    }
                }
            }
    
        }
    
        public static void main(String[] args) throws InterruptedException {
            map.put("tom", 0);
            CorrectUseConcurrentHashMap errorUseConcurrentHashMap = new CorrectUseConcurrentHashMap();
            Thread thread1 = new Thread(errorUseConcurrentHashMap);
            Thread thread2 = new Thread(errorUseConcurrentHashMap);
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println("最终输出值:" + map.get("tom"));
    
        }
    }
    

      最终输出结果:

      

  • 相关阅读:
    poj 2773 利用欧拉函数求互质数
    poj3358:欧拉定理
    poj:2992 因子数量
    poj3696:同余方程,欧拉定理
    USACO5.4-Character Recognition
    hdu5017:补题系列之西安网络赛1011
    hdu5014:number sequence对称思想
    欧拉函数,欧拉定理例题整理
    POJ 3463 Sightseeing (次短路)
    POJ
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12766002.html
Copyright © 2011-2022 走看看