HashMap / HashTable / ConcurrentHashMap

HashMap与HashTable:
  1. HashMap不是线程安全的,HashTabe是线程安全的,并发环境中使用HashMap更容易出现线程安全问题
  2. HashMap的父类是AbstractMap,而HashTable的父类是已经被废弃的Dictionary
  3. HashMap的key和value可以为null,而HashTable的key和value均不能为null
  4. HashMap的哈希算法注重的是哈希算法的效率,当容器容量为2的幂次方时,HashMap对于哈希值的取模运算可以直接以位运算的形式进行取指,速度会比直接取模运算有很大提升,因此HashMap的默认初始容量为16,扩容每次为当前容量的 2 倍。HashTable的哈希算法注重的是元素在哈希桶中是否放置的更加均匀,因此他尽可能的采用奇数或是素数作为容器的容量。HashTable的默认初始值为 11, 扩容数量每次为当前容量的 2n+1。
    PS:由于HashMap对哈希桶的容量进行了处理,虽然取模求得哈希值的效率增加,但是也不可避免的哈希值会有更大的冲突,HashMap为了解决较大的哈希冲突,对哈希值进行了二次哈希运算,目的是为了打散哈希表中的元素。
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
HashTable与ConcurrentHashMap:
  1. ConcurrentHashMap是支持并发的HashMap。
  2. HashTable与ConcurrentHashMap均不允许key或value的值为空。
  3. HashTable与ConcurrentHashMap都是线程安全的,区别在于加锁的方式不同。
    HashTable是将整个容器加锁,而ConcurrentHashMap采用的是分段锁策略。
    当我们使用HashTable时,一个线程使用HashTable时需要对整个容器进行加锁,其他线程必须等待,效率较低。
    当我们使用ConcurrentHashMap时,一个线程仅仅需要使用容器中的一段,那么线程只需要获取该段的锁即可,其他线程依然可以访问其他段的元素,效率较高。

你可能感兴趣的:(HashMap / HashTable / ConcurrentHashMap)