HashMap自身是不安全的,再多线程下不推荐使用,下面主要描述一下HashTable与ConcurrentHsahMap的区别
锁粒度的不同
HashTable加锁是对整个对象加锁,就相当于对整个哈希表进行加锁,这样就很容易导致锁竞争,大大的降低了性能.
ConcurrentHashMap的加锁是不对整个对象进行加锁,而是对每个链表的头节点进行加锁,相当于"锁桶".这样就大大降低了锁冲突发生的概率,也就提升的性能.
ConcurrentHashMap只对写操作进行加锁,并没有对读操作进行加锁
只有当多个线程同时修改一个变量时才会产生锁冲突.
但有一个问题如果当一个线程写的时候,一个线程在读会不会出现读数据的时候读到只修改了一半的数据呢??
答案是不会的,在实现ConcurrentHaspMap的是就考虑到了这个问题,所以可以保证读的数据一定是一个完整的数据,而并不是一个修改到一半的数据
另外读操作是也可会使用volatile来保证数据是及时的
ConcurrentHashMap充分利用了CAS的特性
ConcurrentHashMap对扩容方式也进行了优化
发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去扩容期间, 新老数组同时存在.后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.搬完最后一个元素再把老数组删掉.
这个期间, 插入只往新数组加.查找需要同时查新数组和老数组
HashMap的key允许为null
HashTable和ConcurrentHashMap的key不允许为null