Hashtable是线程安全的,而HashMap不是线程安全的。java
为何说Hashtable是线程安全呢?安全
来看下 Hashtable 的源码,Hashtable 全部的元素操做都是 synchronized 修饰的,而 HashMap 并无。性能
既然 Hashtable 是线程安全的,每一个方法都要阻塞其余线程,因此 Hashtable 性能较差,HashMap 性能较好,使用更广。spa
若是要线程安全又要保证性能,建议使用 JUC 包下的 ConcurrentHashMap(下节重点讲解这个)。线程
Hashtable 是不容许键或值为 null 的,HashMap 的键值则均可觉得 null。那么问题来了,为何 Hashtable 是不容许 KEY 和 VALUE 为 null, 而 HashMap 则能够?3d
Hashtable put 方法逻辑:指针
HashMap hash 方法逻辑:blog
能够看出 Hashtable key 为 null 会直接抛出空指针异常,value 为 null 手动抛出空指针异常,而 HashMap 的逻辑对 null 做了特殊处理。继承
Hashtable 的继承源码:事件
HashMap 的继承源码:
能够看出二者继承的类不同,Hashtable 继承了 Dictionary类,而 HashMap 继承的是 AbstractMap 类。
Dictionary 是 JDK 1.0 添加的,貌似没人用过这个,栈长我也没用过。。
HashMap 的初始容量为:16,Hashtable 初始容量为:11,二者的负载因子默认都是:0.75。
当现有容量大于总容量 * 负载因子时,HashMap 扩容规则为当前容量翻倍,Hashtable 扩容规则为当前容量翻倍 + 1。
HashMap 中的 Iterator 迭代器是 fail-fast 的,而 Hashtable 的 Enumerator 不是 fail-fast 的。因此,当其余线程改变了HashMap 的结构, 如:增 加、删除元素,将会抛出 ConcurrentModificationException 异常,而 Hashtable 则不会。
(先普及一下fail-fast知识。**ail-fast 机制是java集合(Collection)中的一种错误机制。**当多个线程对同一个集合的内容进行操做时,就可能会产生fail-fast事件。例如:当某一个线程A经过iterator去遍历某集合的过程当中,若该集合的内容被其余线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。)
** 能够来看下这个区别的演示:**
Hashtable运行结果:
HashMap运行结果:
看到了吧?因此,这条一样也是 Enumeration 和 Iterator 的区别。
请关注个人博客,这里定时会更新如今主流技术,这里只写大家想学到的,只写大家想要的,简单明了!!!