我们知道hashmap本身是线程不安全的,可以使用concurrenthashmap来实现线程安全
1.7的concurrenthashmap
在1.7版本时,concurrenthashmap是使用分段锁来实现线程安全的,具体来说就是将一整块hashmap分割成多个segment上(默认是16个),每个segment使用reentrantlock来进行线程安全操作,通过这种方式来保障线程安全
1.8的concurrenthashmap
1.8版本concurrenthashmap的实现听起来其实很简单,用cas和synchronized来实现,put流程:
- 计算key的hashcode,经过扰动函数,对长度取模,定位
- 通过cas判断当前位置是否为空,是,就将数据存入,不是,通过synchronized写入数据(链表红黑树判断)。
不论是1.7还是1.8,在这个过程中实际上还有一部分,就是扩容的部分,当某个数据进行插入时判断超出存储阈值(需要扩容时),就会将当前的segment/当前位置的hashcode标记为MOVED,也就是说在扩容,这时如果有其他线程访问发现时MOVED时,就会先停下自己的事,帮助扩容迁移