Lock底层实现原理

1.Lock对象

在这里插入图片描述
Lock底层实现原理_第1张图片

2.获取锁

2.1第一个线程进来

Lock底层实现原理_第2张图片
Lock底层实现原理_第3张图片
他会执行compareAndSetState,对state进行加1操作。然后执AQS类setExclusiveOwnerThread方法,把当前运行的线程赋值给exclusiveOwnerThread

2.2第二次其他线程进来:

当其他线程进来的时候会走else:执行AQS的acquire方法
Lock底层实现原理_第4张图片
执行tryAcquire方法,尝试去获取锁,如果getState是0,那就修改AQS:state的值并赋值当前获取线程锁的线程。执行else,说明还是之前的线程,进行重入
Lock底层实现原理_第5张图片
尝试获取锁失败就会执行addWaiter方法负责把当前无法获得锁的线程包装为一个Node(这个node是包含线程的)添加到队尾。参数mode是独占锁,也叫排它锁。如果当前node队尾不等于空,已经存在值。如果当前队尾没有值,就执行enq方法加入队尾。
Lock底层实现原理_第6张图片
enq方法,当多个线程进来,第一次队尾t是null,就会执行compareAndSetHead方法,他会行创建一个空node放入到ASQ的head里面,ASQ的tail指向head。后面正常加入队尾也就是else,返回node
Lock底层实现原理_第7张图片
执行完addWaiter返回node给acquireQueued方法。当前节点进去,获取前驱节点,判断是否是AQS的头节点,如果是就可以去看锁是否被占用,并将自己设为head,返回false就不用阻塞了
Lock底层实现原理_第8张图片
执行shouldParkAfterFailedAcquire方法,并且获取前驱节点,判断是不是通知状态。如果不是执行ws>0循环(说明前驱放弃了),一直向前找,直到找到状态为小于0才结束,之前CANCELLED状态的前驱都会让他拖链,GC会把拖链的给处理掉。如果是执行else就将前驱设置为通知状态。通知状态就是当前驱执行完之后,通知后面的节点,返回true之后就会执行parkAndCheckInterrupt
在这里插入图片描述
Lock底层实现原理_第9张图片
执行parkAndCheckInterrupt,就是将当前线程进行阻塞
Lock底层实现原理_第10张图片

3.释放锁

tryRelease尝试释放锁,
Lock底层实现原理_第11张图片
tryRelease方法如果线程多次锁定,则进行多次释放,直至status==0则真正释放锁,所谓释放锁即设置status为0,因为无竞争所以没有使用CAS。
Lock底层实现原理_第12张图片
这段代码的意思在于找出第一个可以unpark的线程,一般说来head.next == head,Head就是第一个线程,但Head.next可能被取消或被置为null,因此比较稳妥的办法是从后往前找第一个可用线程。貌似回溯会导致性能降低,其实这个发生的几率很小,所以不会有性能影响。
Lock底层实现原理_第13张图片

你可能感兴趣的:(多线程)