aqs的原理很简单,就是1.锁信息,2.Node同步链
锁信息包含:
1.占用状态-state,大于0就说明锁被占用了
2.当前线程-exclusiveOwnerThread,占用锁的线程,命名排除是因为重入的时候直接排除判断
3.同步链首-head,执行中或者已执行完的Node(执行中的是插队的Node),执行中完成后用唤醒head后的Node
4.同步链尾-tail
Node包含:
1.前Node
2.后Node
3.后Node的等待的行为-waitStatus
我们用例子去理解:
初始状态
exclusiveOwnerThread=null,state=0
Thread0请求
exclusiveOwnerThread=Thread0,state=1
Thread1请求
exclusiveOwnerThread=Thread0,state=1
head => 空Node => Node1 <=tail
Thread2请求
exclusiveOwnerThread=Thread0,state=1
head => 空Node=> Node1 => Node2 <=tail
Thread3请求
exclusiveOwnerThread=Thread0,state=1
head => 空Node => Node1 => Node2 => Node3 <=tail
Thread0执行完成,释放锁,释放head对应Node,唤醒head对应Node的next
exclusiveOwnerThread=Thread1,state=1
head => Node1 => Node2 => Node3 <=tail
Thread1执行完,释放锁,未释放head对应Node,head对应next未占用锁,Thread4请求,成功占用锁,这个就是插队,适用于非公平锁,如果是公平锁,这个地方会多一个判断,判断同步链长度是否大于0,如果大于零,就不能占用锁,只能排队到最后,这步就不会插队,直接到最后排队
exclusiveOwnerThread=null,state=0
head => Node1 => Node2 => Node3 <=tail
Thread4占用=>
exclusiveOwnerThread=Thread4,state=1
head => Node1 => Node2 => Node3 <=tail
Thread4执行完成,释放锁,释放head对应Node,唤醒head对应Node的next
exclusiveOwnerThread=Thread2,state=1
head => Node2 => Node3 <=tail
Thread2执行完成,释放锁,释放head对应Node,唤醒head对应Node的next
exclusiveOwnerThread=Thread3,state=1
head => Node3 <=tail
Thread3执行完成,释放锁,释放head对应Node,唤醒head对应Node的next
exclusiveOwnerThread=null,state=0