ReentrantLock
state变量----》CAS----》失败后进入等待队列----》释放锁后唤醒
默认非公平锁,公平锁需将fair设置为true
synchronized和ReentrantLock的区别
synchronized | ReentrantLock |
系统自动加锁 | 手动加锁 |
synchronized | CAS |
无 | 可tryLock与lockInterruptibly |
非公平锁 | 公平锁、非公平锁 |
AQS:Abstract Queue Synchronizer 抽象队列同步
核心变量
state(volatile的):尝试用CAS方式去更新state=1
等待队列:线程2加锁失败,进入等待队列,挂起
加锁线程:线程1
过程图如下所示
过程描述:
(1)线程1尝试用CAS的方式更新stste=1,加锁成功,当前加锁线程为线程1
(2)线程2尝试CAS的方式更新state=1,发现目前state不等于0,因此进入等待队列挂起
(3)线程1执行完毕,释放锁将state改为0,线程1唤醒等待队列中的线程2
(4)假设当前未设置fair为true,默认为非公平锁
- 当线程2被唤醒,还没上锁时,线程3在这个时候通过CAS的方式获取到锁,更新state=1,当前加锁线程为线程3
- 线程2执行完毕,释放锁,state=0
- 线程2被唤醒,通过CAS的方式获取到锁,更新state=1,当前加锁线程为线程2
- 线程3执行完毕,释放锁,state=0,唤醒等对队列中的线程2
- 线程2尝试CAS的方式更新state=1,发现目前state不等于0,因此进入等待队列挂起
(5)假设当前fair为true,公平锁
- 当线程2被唤醒,还没上锁时,线程3在这个时候过来了,首先检查等待队列,发现其中存在线程2,线程3进入等待队列挂起
- 程3执行完毕,释放锁,state=0
- 线程3在这个时候通过CAS的方式获取到锁,更新state=1,当前加锁线程为线程3
- 线程2执行完毕,释放锁,state=0,唤醒等对队列中的线程3
- 线程2被唤醒,通过CAS的方式获取到锁,更新state=1,当前加锁线程为线程2
非公平锁:默认非公平锁,非公平锁进来时可能刚好获得锁,不用去等待队列
公平锁:fair设置为true,会检查队列中是否存在其他挂起的线程,如果有,当前线程排队进入等待队列挂起
所以非公平锁比公平锁效率高