ConcurrentHashMap简介:一款线程安全的HashMap类集合,底层数据结构采用Node数组 + 链表 /红黑树。java1.7采用Segement(基于ReetrantLock实现)分段锁解决并发安全,java1.8采用CAS + synchronized解决并发安全;java1.8采用CAS + synchronized是为了提高并发性能,CAS保证在需要放入数组元素且数组对应下标元素为null情况下无阻塞尝试放入元素,当需要放入数组元素且对应下标不为null时采用synconized只对首节点加锁,锁粒度相比1.7更小,只要hash不冲突就不会加锁,而且java1.6开始synconized进行了锁优化,并发效率进一步提升。
1.ConcurrentHashMap中线程安全的方法:
①putVal()方法放入一个元素
②replaceNode()方法
③clear()方法
④initTable()方法
⑤addCount()方法
重点是putVal()、initTable()和addCount()方法
putVal()方法源码:
final V putVal(K key, V value, boolean onlyIfAbsent) {
//ConcurrentHashMap要求key和value均不为空
if (key == null || value == null) throw new NullPointerException();
//通过spread()方法获取key的hash
int hash = spread(key.hashCode());
//记录数组某一个下标包含的元素个数(以便最后进行树化的判断)
int binCount = 0;
//自旋加锁
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
//判断Node数组是否需要初始化
if (tab == null || (n = tab.length) == 0)
tab = initTable();
//(n - 1) & hash得到数组下标,tabAt()方法获取此下标元素,判断是否为空
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
//该下标元素位空,尝试使用CAS放