线程安全的容器有以下几种:
Vector,HashTable,concurrentHashMap,,copyOnWriteArrayList
HashMap 和 HashTable 的区别
第一,继承不同,HashMap 继承自 Map类,HashTable 继承自 Dictionary。
第二,HashTable 中的方法是同步的,而 HashMap 中的方法在缺省情况下是非同步的。在多线程开发环境下,可以直接使用 HashTable,HashTable 的实现方法内都加入了 synchronized 关键字来确保线程同步,但要使用 HashMap 就要自己添加同步代码。但 HashTable 的所有线程都在竞争同一把锁,线程数越多,效率越低,这种情况下可以使用 concurrentHashMap,concurrentHashMap 使用的是分段锁,当不同的线程在写不同的 segment 时互不干扰,避免了竞争同一把锁,提高了效率。
第三, hashTable 中,key 和 value 都不允许出现 null 值,HashMap 中可以有一个 null键以及多个 null 值。在 HashMap 中,当 get() 方法返回 null 值时,既可以表示 HashMap 中没有该键,也可以表示该键对应的值为 null。因此,在 hashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键,而应使用 containsKey() 方法来判断。
第四,两个遍历方式的内部实现不同,HashTable、HashMap 都使用了 Iterator。而由于历史原因,HashTable 还使用了 enumeration 的方式,另一个区别是 HashMap 的迭代器(Iterator)是 fail-fast 的,而 HashTable 的迭代器(enumeration)不是fail-fast 的。
第五,哈希值的使用不同,HashTable 直接使用对象的 HashCode,而 hashMap 重新计算 hash 值。
第六,HashTable 和 HashMap 他们两个内部实现方式的数组的初始大小和扩容方式不同。HashTable 中 hash 数组默认大小是11,增加的方式是 old*2+1;HashMap 中 hash 数组大小默认是16,增加的方式是直接翻倍。
第七,HashTable 求数组下标是通过对 length 取余,HashMap 则是通过对 length-1 进行与运算