• HashMap和HashTable


    两者的父类不同

    HashMap是继承自AbstractMap类,而HashTable 是继承自Dictionary类.不过他们都实现了Map Cloneable Serializable这三个接口.

    对null的支持不同

    HashTable:key和value都不能为null

    HashMap:key可以为null,但是这样的key只能有一个,因为必须保证key的唯一性;可以有多个key值对应的value为null

    安全性不同

    HashMap是线程不安全的,在多线程并发的环境下,可能产生死锁等问题,因此需要开发人员自己处理多线程问题.

    HashTable是线程安全的,它的每个方法上都有synchronized关键字,因此可以直接用于多线程中.

    虽然HashMap不安全,但是它的效率远远高于HashTable,这样设计是合理的,因为大部分的使用场景都是单线程的.当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap.

    ConcurrentHashMap虽然也是线程安全的,但是它的效率比HashTable要高好多倍.因为ConcurrentHashMap使用了分段锁,并不多整个数据进行锁定

    初始容量大小和每次扩充容量大小不同

    HashMap初始化默认的数组大小只有16,自动扩容是翻一倍
    HashTable 初始化默认是 11 (除质数球余的分散效果好),自动扩容是两倍+1(奇数)

    计算hash值的方法不同

    • HashMap
        static final int hash(Object key) {
            int h;
            return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        }
    

    上面可以看出key可以为null,key值的hash值的计算方法为:** key的hashCode的高16位不变,低16位与高16位异或的结果作为低16位的结果.(h>>>16,表示无符号右移16位,高位补0)**

    • HashTable
    int hash = key.hashCode();
    int index = (hash & 0x7FFFFFFF) % tab.length
    

    直接使用key的hashCode,但是为了在hashCode为负数的情况下,取出负数,所以和0x7FFFFFFF (二进制为0111 1111 1111 1111 1111 1111 1111 1111) 负数和其& 操作将产生一个正数.

    扩展

    分段锁

    容器里面有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里面不同数据段的数据时,线程间就不会存在锁竞争,从而有效提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一段数据的时候,其他段的数据也能被其他线程访问.

  • 相关阅读:
    了解大数据的特点、来源与数据呈现方式
    作业四 简单四则运算
    阅读《构建之法》1-5章有感
    分布式版本控制系统Git的安装与使用
    第一次作业-准备
    dubbo相关
    SSL相关
    关于serialize和serializearray在JS和JQuery的区别
    Log4j 的日志级别
    关于CSS中display
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/14027054.html
Copyright © 2020-2023  润新知