HashMap与Hashtable的对比

HashMap为什么线程不安全

  • 多线程 put 操作后, get 操作导致死循环,导致 cpu100%的现象。 主要是多线程同时put 时, 如果同时触发了 rehash 操作, 会导致扩容后的 HashMap 中的链表中出现循环节点, 进而使得后面 get 的时候, 会死循环。关于死循环具体形成,可见 HashMap的死循环(HashMap infinite loop)
  • 多线程 put 操作, 导致元素丢失, 也是发生在多个线程对 hashmap 扩容时。

二者的区别与联系

  • Hashtable和HashMap,从存储结构和实现来讲基本上都是相同的。它和HashMap的最大的不同是它是线程安全的(通过对put,remove等方法用synchronize关键字修饰),另外它不允许key和value为null。Hashtable是个过时的集合类,不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。但这并不是我们不去了解它的理由。
  • Hashtable是如何实现线程安全的的?
    通过对put,remove等方法用synchronize关键字修饰,通过源码可以看到
  • HashTable 的效率比较低的原因
    在线程竞争激烈的情况下 HashTable 的效率非常低下。 因为当一个线程访问HashTable 的同步方法时, 访问其他同步方法的线程就可能会进入阻塞或者轮训状态。 如线程 1 使用 put 进行添加元素, 线程 2 不但不能使用 put 方法添加元素, 并且也不能使用get 方法来获取元素, 所以竞争越激烈效率越低
  • 判断是否含有某个键问题

    • 在 HashMap 中, null 可以作为键, 这样的键只有一个; 可以有一个或多个键所对应的值为 null。 当 get()方法返回 null 值时, 既可以表示 HashMap 中没有该键, 也可以表示该键所对应的值为 null。 因此, 在 HashMap 中不能用 get()方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey()方法来判断。
    • Hashtable 的键值都不能为 null, 所以可以用 get()方法来判断是否含有某个键。
  • Hashtable和HashMap的不同点?
    这里写图片描述

猜你喜欢

转载自blog.csdn.net/zjxxyz123/article/details/81141927