一、独占锁获取源码
在上节中,我们学习了AQS的基本概念,并手动实现了一个独占锁,以及相应的数据结构:节点和同步队列
接下来我们来看一下独占锁的源码
当我们采用独占式获取时,我们在lock方法中调用其模板方法acquire
public void lock() {
//子类覆盖的是流程方法tryAcquire,这里调用父类的模板方法acquire
sync.acquire(1);//模板方法
}
我们来看一下acquire模板方法
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();//该方法就是执行Thread.currentThread().interrupt();
}
tryAcquire方法: 尝试获取锁
addWaiter方法:把Node节点加入同步队列中,参数Node.EXCLUSIVE是独占锁,Node.SHARED 是共享锁
acquireQueued方法:一旦加入同步队列,就需要使用该方法,自旋阻塞唤醒来不断的尝试获取锁,直到被中断或获取到锁,这里需要看源码加深理解
1.1 tryAcquire方法
我们自己实现的流程方法,通过CAS方式设置同步标志位,设置成功表示拿到锁
protected boolean tryAcquire(int arg) {
assert arg == 1;
//cas将状态从0设为1,如何不为0则失败
if(compareAndSetState(0,1)){
return true;