1、ConcurrentHashMap的实现原理和使用
1.1、使用ConcurrentHashMap的原因:
(1)线程不安全的HashMap:HashMap在并发操作的时候执行put操作会引起死循环,是因为多线程会导致HashMap的Entry链表会形成环形的数据结构,一旦形成环形的数据结构,Entry的next节点永不为空,就会产生死循环获取entry。
(2)HashTable效率低下
1.2、ConcurrentHashMap的结构
ConcurrentHashMap是由Segment数据结构和HashEntry数据结构组成的。Segment是一种可重入锁,HashEntry用于存储键值对数据,当发生并发时,只需要锁住对应的Segment即可(Se1gment一共有16个),这样大大增强了程序的并发性。
1.3、ConcurrentHashMap的操作
1、get操作:先经过一次再散列,然后使用这个散列值通过散列运算定位到Segment,再通过散列算法定位到元素。get操作的高效之处在于整个get过程不需要加锁,除非读到的是空值才会加锁重读。
2、put操作:由于put方法需要对共享变量进行写入操作,因此为了线程安全,在操作共享变量的时候必须要加锁。put方法首先定位到Segment,然后在Segment里进行插入操作。插入操作需要经过两个步骤:第一步是判断是否需要对Segment里面的HashEntry数组进行扩容,第二步定位添加元素的位置,然后将其放在HashEntry数组里面。
扩容的方法:在扩容的时候,首先会创建一个容量是原来容量两倍的数组,然后将原来数组中的元素进行再散列之后插入到新的数组中。为了高效,ConcurrentHashMap不会对整个容器进行扩容,而是只会对某个segment进行扩容。
后续的ConcurrentLinkedQueue以及BlockingQueue还需要进行额外的阅读和补齐
原创文章,作者:306829225,如若转载,请注明出处:https://blog.ytso.com/278273.html