前言
前段时间摸鱼看了看源码,结合自己的想法简单记录一下两者的原理。
一、ConcurrentHashMap的结构与实现原理:
JDK1.7之前使用了分段锁segment,继承了ReentrantLock。每个segment下都有课有多个Node,上锁的时候是锁住segment。一共有16个segment,所以可以支持16个线程的并发。
JDK1.8之后使用的是CAS和Synchronized方式处理并发,同时Node[]被volatile修饰。会对所有Node[]里的节点做CAS,Synchronized则是对链表加锁。且1.8后ConcurrentHashMap会根据map的长度是否大于TREEIFY_THRESHOLD(8默认是8)决定使用链表还是红黑树。
二、ReentrantLock的原理
ReentrantLock是可重入的互斥锁。包含公平锁和非公平锁
ReentrantLock里的state是用volitle修饰的,全局根据state的状态知道当前是否被任何线程持有(0.没有被持有1.被其他线程持有),如果持有锁的线程,再次获取同一把锁,直接成功。然后state状态+1,释放时-1,所以占有了多少次锁,就需要释放多少次。
公平锁实现了AQS队列,试图获取锁的线程都会被加进这个队列中,新来的线程会把加入到队列的尾部,当前线程释放锁后,就会冲队列中找出头部的线程竞争获取锁。
非公平锁同样会加入队列,但是当锁释放时,会让当前竞争锁的线程(可能是刚来的)和头部的线程竞争,竞争成功就获取锁,失败就加入队列尾部。