HashMap、HashTable、ConcurrentHashMap的区别与联系
HashMap、HashTable、ConcurrentHashMap是我们Java中常用几种Map,它们各自有着各自的特点,也有着共同的联系,今天我们一起总结回顾一下这三种常用的数据结构。
首先来看一下它们的定义。
HashMap:
继承自AbstractMap,实现了Map、Cloneable、Serializable接口。
HashTable:
可以看到HashMap与HashTable并不是继承自同一个父类。但实现的接口是一样的。
ConcurrentHashMap:
ConcurrentHashMap与HashMap都继承自AbstractMap,但它实现的ConcurrentMap也是继承了Map。
看完了定义我们来看一下它们的主要区别:
一:键值(Key Value)是否可以为null
HashTable:
在put方法的注释中明确写到了Key ,Value不能为null。我们看到在put方法调用时,第一时间就会判断value是否为null,如果是就会报空指针异常。
ConcurrentHashMap:
在源码中我们看到,ConcurrentHashMap中也不能将Null作为Key、Value。
HashMap:
HashMap中并没有判断null值得方法,所以HashMap中可以存放一个Null键和多个Null值。
总结:HashMap中Key、Value可以为Null,HashTable和ConcurrentHashMap中不能出现Null值。
二:效率与线程安全
HashMap:
HashMap中方法没有做同步,效率比HashTable高,但多线程访问同一个HashMap时,可能会出现并发问题。
HashTable:
HashTable中对所有方法都加了同步,操作时会锁死整个表,所以效率低,安全性高。
ConcurrentHashMap:
ConcurrentHashMap中,由于它的结构是由多个Segment数组组成(默认为16个),在操作数据时,只会对操作的Segment数组加锁,所以在最好情况下可以有16个线程同时操作同一个ConcurrentHashMap。(关于ConcurrentMap的结构,参看下一篇博文)
总结:HashMap由于没有对方法加锁,所以不用考虑同步的性能消耗,效率高,安全性低;HashTable安全性能好,但操作时要锁住整张表,效率低;ConcurrentHashMap,既保证了安全性,又能最大程度上的提高性能。
三:HashMap的同步
HashMap有没有办法实现同步呢,当然有。
通过这个方法,我们可以将HashMap同步。
注:此篇文章只是对HashMap、HashTable、ConcurrentHashMap的粗略介绍,如果想更深入的了解,请阅读JDK源码。