使用Collections包装线程不安全的类,使其成为线程安全的类,使用的是sync,效率并无实质提升:
concurrent包下的线程安全集合:blocking,copyonwrite,concurrent。
coucurrentMap每个方法都是原子的,但是几个方法的组合并不是原子的。concurrentMap是细粒度的锁。普通的HashMap在扩容的时候会有并发死链的问题。
ConcurrentHashMap的原理:‘
ConcurrentHashMap在扩容时保证线程安全:
在扩容过程中,处理完毕的链表头节点置为fnode,表明此链表已经处理完毕。其他线程来get,则会到新的线程中去get。
TreeBin是红黑树的头结点,TreeNode是红黑树的树节点。
整个get流程:
hash为负数则去新的扩容的HashMap查找元素。
ConcurrentHashMap不允许有空的键值,put的过程中,只有发生下标冲突,才会使用sync,而且锁的是桶的头节点。
初始化HashTable,只有一个线程成功,只有一个线程cas成功,然后初始化哈希表:
addCount:当哈希表put成功后,增加计数。
put流程,插入新值:
进入下面的else,说明桶下标冲突了,此时需要对链表头节点加锁,fh >= 0,说明是普通节点,进行普通的插入流程即可,bigcount代表链表长度。
节点的类型是红黑树:
bigcount(节点数)和门限值比较,看是否需要转化为红黑树: