ReentrantLock解锁流程

上篇介绍了ReentrantLock的加速流程,传送门:https://blog.csdn.net/qq_25178353/article/details/107568396 有加锁就有解锁,接下来探讨一下解锁的流程。解锁流程总体来说比这加锁简单。先上流程图:

解锁流程从调用lock.unlock()开始,lock.unlock()方法调用的是sync.release(1)方法,sync.release(1)的代码如下:

    public final boolean release(int arg) {if (tryRelease(arg)) {//当 tryRelease返回true 即 c == 0 时 ,//需要唤醒头结点的后继节点Node h = head;// 当waitStatus == -1 时说明后继节点正在park中需要unpark// 当waitStatus == 0时,后继节点是不会park的会在竞争一轮锁if (h != null && h.waitStatus != 0)unparkSuccessor(h);return true;}return false;}

release(int arg) 方法是sync的父类AbstractQueuedSynchronizer实现的,其调用了tryRelease(arg),tryRelease(arg)跟tryAquire一样,在AQS里面 没有具体实现,需要子类实现,下面贴出ReentrantLock的tryRelease(arg) 的代码:

        protected final boolean tryRelease(int releases) {// 获取本次释放锁后state的值 执行unlock时一般为 release的值为1int c = getState() - releases;// 若当前线程不是拥有锁的线程,则抛出异常,只有拥有锁的线程才可以释放锁if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;// 若本次解锁后 c 的值为0 说明该线程已经完全释放了锁// 若c不为0,则是在多次重入的情况下。if (c == 0) {free = true;setExclusiveOwnerThread(null);}//当c == 0时,这一步执行完,该线程就真正释放了锁,其他线程就可以拥有锁了,//因为还没有执行unpark方法,还没有唤醒该线程的后继节点的线程,//所以在非公平锁的情况下,未入队的线程比这等待队列里的线程更容易竞争到锁setState(c);return free;}

tryRelease后,(若锁的状态为0(即state == 0)&& 等待队列不为空 && head.waitStatus != 0) 就可以唤醒head的后继节点。关于waitStatues !=0 这个条件,这里做一下简要说明:waitStatus ==0 时,改节点的后继节点还没有park所以不需要unpark。下面看一下unparkSuccessor(h)的代码:

    private void unparkSuccessor(Node node) {int ws = node.waitStatus;if (ws < 0)// 尝试将ws改为 0 ,即使失败也无所谓。// 这里使用cas的方式修改是因为他的前置节点也可能修改他的waitStatus// 将ws更新为0的理由是让唤醒的线程可以多一轮竞争。提高竞争率compareAndSetWaitStatus(node, ws, 0);Node s = node.next;// 当头结点的后继节点为空或者已经被取消时if (s == null || s.waitStatus > 0) {s = null;// 从队尾开始向前遍历知道找到一个活着的可唤醒的线程for (Node t = tail; t != null && t != node; t = t.prev)if (t.waitStatus <= 0)s = t;}if (s != null)LockSupport.unpark(s.thread);}

unparkSuccessor是AQS的一个私有方法,只能该类内部调用。当调用完LockSupport.unpark(s.thread)方法后,唤醒在park状态的线程s.thread。唤醒不等于拥有锁,因为s.thread被唤醒后需要通过tryAcquire() 方法去竞争,如果竞争失败则在竞争一次如果两次都没有竞争则继续阻塞,等着获取的线程再次唤醒自己。

ReentrantLock解锁流程相关推荐

  1. android keyguard,Android8.1 SystemUI Keyguard之指纹解锁流程

    手指在指纹传感器上摸一下就能解锁,Keyguard是怎么做到的呢? 下面我们就跟着源码,解析这整个过程. 何时开始监听指纹传感器? 先来看下IKeyguardService这个binder接口有哪些回 ...

  2. Android sim卡 pin码解锁流程.

    sim卡 pin码解锁流程 1. PIN码解锁界面属于Phone Policy的一部分,代码位置在 \frameworks\base\policy\src\com\android\internal\p ...

  3. 第5章 SIM卡锁定PIN解锁流程

    第5章 SIM卡锁定PIN解锁流程 1.插卡后,在卡初始化过程中,UiccController会从底层获取card状态,会知道要不要进行PIN校验,如果开启就暂停卡初始化流程,并弹出PIN输入框,输入 ...

  4. 指纹录入和指纹解锁流程

    粗略了解下指纹的录入和解锁流程, 记录如下 Android P Finger Enroll:     1.Settings         FingerprintEnrollIntroduction ...

  5. EFM32芯片jlink无法连接,无法调试,解锁流程

    4.2.2 解锁 (1)按照前文硬件连接要求将JLink仿真器的调试接口与MCU系统调试接口进行连接.然后将仿真器连接到电脑USB端口上,并将EFM32LG230F128系统上电: (2)运行JLin ...

  6. android指纹解锁动画,Android8.1 SystemUI Keyguard之指纹解锁流程

    手指在指纹传感器上摸一下就能解锁,Keyguard是怎么做到的呢? 下面我们就跟着源码,解析这整个过程. 何时开始监听指纹传感器? 先来看下IKeyguardService这个binder接口有哪些回 ...

  7. android 解锁流程,Android Q 指纹解锁流程

    Android Q 指纹解锁流程 // Authentation Finger Schedule: (close Screen, Authentation with finger(Success)) ...

  8. Android Mediatek bootloader oem锁定和解锁流程

    目录 修改的文件: 文件修改说明: 这个修个是在mtk android11上的 , 就是个进入oem解锁流程  , 下面这部分代码就是开机检测按键 , 然后进入不同模式的.如果要修改其他的 也是大同小 ...

  9. Android11 九宫格解锁流程

    在我们分析完锁屏的一整个显示流程后,我们接着来分析一下上滑解锁的流程. 流程 首先,我们手指在锁屏界面上滑将会调用StatusBar中的onTrackingStopped方法 public void ...

最新文章

  1. mysql内连接和外连接的区别_Swoole4创建Mysql连接池
  2. 区块链安全:2019年我们走了多远?
  3. 限定项目的 Node.js 版本
  4. php面向对象中的魔术方法中文说明
  5. itemcf的hadoop实现优化(Python)
  6. Scala父类和父特质的执行顺序
  7. CSS 文字显示在图片的中间
  8. maven 之 setting.xm 的配置详解、说明
  9. [转载] Python中的xrange和range的区别
  10. gezabo变黑闪退,报错[gazebo_gui-2] process has died
  11. 本周开源论文推荐:含人脸识别、实例分割、跟踪、SR等
  12. 使用memcachedclientXmemcached与Spring整合
  13. 你们一般持有几支基金?怎么管理的?
  14. SQL SERVER 2008数据库管理与维护总结
  15. 蓝桥杯 算法训练 矩阵乘法
  16. 妇产科护理学名词解释
  17. Mysql orchestrator高可用
  18. [半监督学习] Combining Labeled and Unlabeled Data with Co-Training
  19. 第26讲:多表查询之自连接
  20. STARK代码详细学习笔记

热门文章

  1. TELNET协议笔记
  2. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A
  3. 【BZOJ 2844】 albus就是要第一个出场
  4. 彻底关闭windows Update服务
  5. SCU 4437 Carries 想法题
  6. Linux C++服务器项目——网络编程2(三次握手、四次挥手、IO多路复用)
  7. Picasso框架源码解析(一)。
  8. 林登实验室在Second Life中为教育工作者提供的官方资源
  9. python-对水平和垂直投影图做曲线拟合
  10. html励志素材,名人励志故事素材