zoukankan      html  css  js  c++  java
  • ConcurrentHashMap详解

    一、背景

    线程不安全的HashMap

    因为多线程环境下,使用HashMap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap。

    效率低下的HashTable容器

    HashTable容器使用的synchronized来保证线程安全,但是在线程竞争激烈的情况下,HashTable的效率非常低下。因为当一个线程访问HashTable的同步方法时,其他线程访问HashTable的同步方法会进入阻塞或者轮询状态。如果线程1使用put进行添加元素,线程2不但不能使用put方法添加元素,并且不能使用get方法来获取元素,所以竞争越激烈效率越低。

    锁分段技术

    HashTable容器在竞争激烈的并发环境下表现出效率低下的原因,是因为所有访问HashTable的线程都必须竞争同一把锁,那假如线程里面有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里面不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效提高并发访问效率。这就是ConcurrentHashMap使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁。

    源码:

     这些是ConcurrentHashMap是最容易做大梅毒名称传播。

    我们来看一下ConcurrentHashmap的性能

    package com.study.mapdemo;
    
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Hashtable;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class TestConcurrentHashMap {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            final Map<Integer, Integer> hm = Collections.synchronizedMap(new HashMap<Integer, Integer>());
            final Map<Integer,Integer> ht = new Hashtable<Integer, Integer>();
            final Map<Integer,Integer> chm = new ConcurrentHashMap<Integer, Integer>();
            putMap(hm);
            putMap(ht);
            putMap(chm);
        }
        
        private static void putMap(final Map<Integer,Integer> map) {
            long begin = System.currentTimeMillis();
            for(int k = 0;k<100;k++) {
                for(int i = 0;i<1000;i++) {
                    final int key = i;
                    new Thread(new Runnable() {
                        
                        @Override
                        public void run() {
                            for(int j = 0;j<3000;j++) {
                                map.put(key,j);
                            }
                            
                        }
                    }).start();
                }
            }
            long end = System.currentTimeMillis();
            System.out.println(end-begin);
        }
    
    }

    代码输出:

    22409
    21260
    15234

    可以看到ConcurrentHashMap的性能更高,速度更快。当数据量较大是,ConcurrentHashmap的性能大概是另外两个的3倍左右。

  • 相关阅读:
    js 字符串转化成数字
    SDK编程之多线程编程
    C/C++内存泄漏及检测
    那些争议最大的编程观点(转)
    DB2日常维护——REORG TABLE命令优化数据库性能(转)
    ireport报表学习
    自定义hexo的某个主题
    mac下搭建码云gitee+hexo博客
    python日期及时间格式转换
    python获取中文首字母
  • 原文地址:https://www.cnblogs.com/LoganChen/p/13311281.html
Copyright © 2011-2022 走看看