ReentrantLock实现细节
ReentrantLock支持两种获取锁的方式,一种是公平模型,一种是非公平模型。
总结:
- 公平锁(先进来的线程先执行)
- 非公平锁(后进来的也可能先执行)
简化版的步骤:(非公平锁的核心)
基于CAS尝试将state(锁数量)从0设置为1
CAS算法详解
A、如果设置成功,设置当前线程为独占锁的线程;
B、如果设置失败,还会再获取一次锁数量,
B1、如果锁数量为0,再基于CAS尝试将state(锁数量)从0设置为1一次,如果设置成功,设置当前线程为独占锁的线程;
B2、如果锁数量不为0或者上边的尝试又失败了,查看当前线程是不是已经是独占锁的线程了,如果是,则将当前的锁数量+1;如果不是,则将该线程封装在一个Node内,并加入到等待队列中去。等待被其前一个线程节点唤醒。
简化版的步骤:(公平锁的核心)
获取一次锁数量,
B1、如果锁数量为0,如果当前线程是等待队列中的头节点,基于CAS尝试将state(锁数量)从0设置为1一次,如果设置成功,设置当前线程为独占锁的线程;
B2、如果锁数量不为0或者当前线程不是等待队列中的头节点或者上边的尝试又失败了,查看当前线程是不是已经是独占锁的线程了,如果是,则将当前的锁数量+1;如果不是,则将该线程封装在一个Node内,并加入到等待队列中去。等待被其前一个线程节点唤醒。
当A线程获取到锁之后进行执行中,将state+1,此时其他线程如果想要执行需要睡眠进行等待,等待A执行完毕后,释放锁后,获取到锁之后才可以执行。
疑问:
- state有什么用途,当线程A在执行的时候,A再次去获取锁了是什么样一种情况?
答:还没有找解释
- 当A再次获取锁之后,state+1,state 的数字大小对应的什么意思?
答:还没有找到解释
- 如果在不公平模式下,当A线程执行完毕后释放锁,B线程是在C线程前面先来再睡眠中,但是在A释放完锁后有可能被C线程所抢到,在外面不是应该有一个队列,应该看到B线程在等待,C线程也应该加入队列中啊。
答:当线程A释放的瞬间,此时,锁是属于真空期,但是B线程被唤醒是需要一定的时间,所以C线程过来看到锁是真空期,不用排队直接获取了。