1.先看一下类图
2.开始跟代码
找一个入口
new ReentrantLock()默认是非公平锁,false是非公平
进入lock.lock(),在 ReentrantLock中的实现
看到是sync的lock方法 Sync 是ReentrantLock的子类
找抽象方法lock()在非公平锁中的实现
compareAndSetState(0,1) 如果状态是0 更新为 1
setExclusiveOwnerThread(Thread.currentThread()); 设置持有线程为当前线程
如果当前状态不是0,则 运行 acquire(1)
看!tryAcquire(arg)方法,进入是一个
找他在非公平锁中的实现
显然状态不是0,当前线程也不是线程执行占有者 返回false;
返回到这张图:!tryAcquire(arg) == true
再看另一个条件 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
进入代码前先看一下Node的几个状态
再看addWaiter(Node.EXCLUSIVE) 添加等待者,为当前线程创建一个队列节点
现在AQS的tail == null,所以直接进入enq(node);
一个自旋,
第一次循环t==null, AQS的head和tail 都设置成 new Node();
第二次循环 t != null 这个新结点 前指针指向当前线程,tail也指向当前线程
返回到 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
final Node p = node.predecessor();获取node的prev节点,而第一个节点是一个空节点 哨兵节点 p == head is true 如果再次尝试获取(tryAcquire(arg))失败返回false lock()方法结束 但是再次尝试获取失败 进入 if (shouldParkAfterFailedAcquire(p, node) &&parkAndCheckInterrupt())
pred.waitStatus 节点默认为0, 运行 compareAndSetWaitStatus(pred, ws, Node.SIGNAL)
把pred.waitStatus 设置成 -1 ,再次循环进来 返回 true;
再 回到AQS870行 运行 parkAndCheckInterrupt() 挂起当前线程
到现在lock方法结束;当遇到unpark方法后继续循环 再次尝试获取(tryAcquire(arg);成功后
释放 哨兵节点(第一个节点) 把当前节点 设置成head 作为哨兵节点.
继续看unlock方法 ReentrantLock中
AQS中:
tryRelease(arg) 尝试释放,在ReentrantLock中实现
因为当前持有锁 getState() = 1 int c = getState() - releases, set State = 0 设置占有线程为null retrun true;
返回AQS的release方法
lock()方法时候 h.waitStatus = -2 运行 unparkSuccessor(h);
head节点 状态小于0,设置为0,next 节点不为null,执行 LockSupport.unpark(s.thread) 唤醒;