一、出现版本的不同
出现的年代不同,在实现方式及性能上也存在较大的不同
- Hashtable:JDK1.0 中出现;JDK1.2 版本中实现了 Map 接口
- ConcurrentHashMap:JDK1.5 中出现的
二、实现线程安全方式的不同
Hashtable 实现并发安全是通过 synchronized 关键字
ConcurrentHashMap 通过cas,node,synchronized 相结合的方式实现
三、性能不同
- Hashtable:
- 线程数量增加的时候性能会急剧下降
- 每一次修改都需要锁住整个对象,其他线程在此期间不能操作
- 会有额外的上下文切换等开销
- ConcurrentHashMap:
- 仅会对一部分上锁而不是全部都上锁
- 并发效率上,ConcurrentHashMap 比 Hashtable 提高了很多
四、迭代时修改的不同
Hashtable(包括HashMap)不允许在迭代期间修改内容,否则会抛出ConcurrentModificationException 异常,其原理是检测 modCount 变量
迭代器的 next() 方法的代码如下:
public T next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
return nextElement();
}
- 每次执行
next()
方法的时候,都会去判断modCount
是否会等于expectedModCount
,如果不相等就会抛出ConcurrentModificationException
-
expectedModCount
是在迭代器生成的时候随之生成的而且不会改变,他所代表的的含义是当前 Hashtable 被修改的次数 - 每次去调用 Hashtable 中的
addEntry()
remove()
reHash()
时,都会修改modCount
的值 - 所以只要在迭代的时候去修改 Hashtable 那么就一定会发生
modCount != expectedModCount
的情况,那么就会抛出ConcurrentModificationException
ConcurrentHashMap 即便在迭代期间修改内容,也不 会抛出ConcurrentModificationException
网友评论