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"));
    
        }
    }
    

      最终输出结果:

      

  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12766002.html
Copyright © 2011-2022 走看看