首页 > 其他分享 >Wandering(1)

Wandering(1)

时间:2023-03-04 18:13:08浏览次数:48  
标签:ConcurrentHashMap 加锁 结点 JDK8 线程 Wandering 死循环

分布式缓存

CDN

反向代理

本地

分布式

ConcurrentHashMap 解决HashMap并发死循环

hashmap并发死循环原理

参考用例

前提:线程1进行到了扩容后的第一步,记录当前节点为3,下一个为7;线程2扩容完并重新散列完。接下来线程1继续工作,e=7,读取线程2重新散列完的map,得到next=3;接下来把3用头插法塞到最前面,同时记录next=7,fine,开始死循环。

死锁和死循环:死锁是因为无法获得资源陷入僵持,死循环是一直在跑,但跑不出去。

JDK8中ConcurrentHashMap参考了JDK8 HashMap的实现,采用了数组+链表+红黑树的实现方式来设计。

红黑树

参考教程

看完教程后可以直接理解具体操作

用五条定义来近似平衡树,并不追求完美平衡,以此换速度。用红黑结点将2-3-4树转化为二叉树,也表达了一种父子关系。插入时将插入结点 视作红色节点,避免红-红左倾、右倾或单链结构的产生;删除时进行染色,通过转化为3/4结点的方式避免删除2结点。

JDK1.7中ConcurrentHashMap分为好几个segment,每个segment加锁。segment中再次hash找到entry。内部大量采用CAS操作,这里我简要介绍下CAS。CAS是compare and swap的缩写,即我们所说的比较交换。cas是一种基于锁的操作,而且是乐观锁。

悲观锁

访问加锁,一个线程访问完另一个再访问。

乐观锁

先获取一个值,操作时比较一下获取的值和当前值是否相同,如果相同,进行操作。

乐观锁和悲观锁

JDK8中彻底放弃了Segment转而采用的是Node,其设计思想也不再是JDK1.7中的分段锁思想。

Node:保存key,value及key的hash值的数据结构。其中value和next都用volatile修饰,保证并发的可见性。

volatile关键字

相对加锁较为轻量级,有两个特点:一是更新时对内存可见,即更新时强制将线程本地缓存刷新到主内存中,并使得其他线程缓存无效;二是防止编译器对指令重排。该关键字不适合复合操作,如ans++,即不保证原子性。

部分源码分析:深入浅出ConcurrentHashMap1.8

明天看redis  2022/3/4


 

 

 

 

标签:ConcurrentHashMap,加锁,结点,JDK8,线程,Wandering,死循环
From: https://www.cnblogs.com/capterlliar/p/17178746.html

相关文章