转载请注明出处:http://blog.csdn.net/luonanqin

上一篇讲了ReentrantLock的lock-unlock流程,今天这篇讲讲Condition的await-signal流程。

Condition类图:

  • Condition接口包含了多种await方式和两个通知方法
  • ConditionObject实现了Condition接口,是AbstractQueuedSynchronizer的内部类
  • Reentrantlock的newCondition方法返回与某个lock实例相关的Condition对象

和release队列一样,Condition队列也是虚拟队列,每个Node通过nextWaiter进行关联。因为Condition Node要变为release Node才可以解除阻塞,所以不需要prevWaiter,这一点下面会有说明。

大概的整个过程是:

调用await的线程都会进入一个Condition队列。调用signal的线程每一次都会从firstWaiter开始找出未取消的Condition Node放到release队列里,然后调用signal的线程在await或者unlock的时候执行release方法才有机会将其解除阻塞。相对于lock-unlock,正常的流程要简单一些,但是对于中断处理会更为复杂。

先看看调用await()至阻塞的过程

如图所示,该过程可分为三个步骤:

  1. 新建Condition Node包装线程,加入Condition队列
  2. 释放当前线程占用的锁
  3. 阻塞当前线程
在阻塞当前线程之前,要判断Condition Node是否在release队列里。如果在的话则没必要阻塞,可直接参与锁竞争。关键代码如下:
 
 
       signal方法更简单一些,就是从firstWaiter开始,找到一个没有取消的Node放入release队列。但是即使一开始找到的Node没被取消,但是入队列的时候也可能会被取消,因此代码对这个情况做了点特殊处理。我根据自己的理解将代码做了如下解释:

我们可以看到,signal方法只是将Node修改了状态,并没有唤醒线程。要将修改状态后的Node唤醒,一种是再次调用await(),一种是调用unlock()。这两个方法内部都会执行release方法对release队列里的Node解除阻塞,关于这点我在上一篇文章里已经说明了。

 
下面我把调用await()的线程被解除阻塞后的流程也画了一下:
 
以上就是await和signal的详细流程。signalAll和signal很像,内部就是将Condition队列里所有的Node都加入到release队列中,仅此而已。

之后有时间我会把一些中断处理也用流程图描述下发出来。

参考资料:

怎么理解Condition   http://www.liuinsect.com/2014/01/27/how_to_understand_condition/

Condition的await-signal流程详解的更多相关文章

  1. C++的性能C#的产能?! - .Net Native 系列《二》:.NET Native开发流程详解

    之前一文<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥> 获得很多朋友支持和鼓励,也更让我坚定做这项技术的推广者,希望能让更多的朋友了解这项技术,于是先从官方 ...

  2. [nRF51822] 5、 霸屏了——详解nRF51 SDK中的GPIOTE(从GPIO电平变化到产生中断事件的流程详解)

    :由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) . ...

  3. 迅为4412开发板Linux驱动教程——总线_设备_驱动注册流程详解

    本文转自:http://www.topeetboard.com 视频下载地址: 驱动注册:http://pan.baidu.com/s/1i34HcDB 设备注册:http://pan.baidu.c ...

  4. Linux启动流程详解【转载】

    在BIOS阶段,计算机的行为基本上被写死了,可以做的事情并不多:一般就是通电.BIOS.主引导记录.操作系统这四步.所以我们一般认为加载内核是linux启动流程的第一步. 第一步.加载内核 操作系统接 ...

  5. iOS 组件化流程详解(git创建流程)

    [链接]组件化流程详解(一)https://www.jianshu.com/p/2deca619ff7e

  6. git概念及工作流程详解

    git概念及工作流程详解 既然我们已经把gitlab安装完毕[当然这是非必要条件],我们就可以使用git来管理自己的项目了,前文也多多少少提及到git的基本命令,本文就先简单对比下SVN与git的区别 ...

  7. Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)

    一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...

  8. JPEG图像压缩算法流程详解

    JPEG图像压缩算法流程详解 JPEG代表Joint Photographic Experts Group(联合图像专家小组).此团队创立于1986年,1992年发布了JPEG的标准而在1994年获得 ...

  9. unity3d-配置Android环境,打包发布Apk流程详解

    31:unity3d-配置Android环境,打包发布Apk流程详解 作者 阿西纳尼 关注 2016.08.28 22:52 字数 498 阅读 1806评论 0喜欢 5 Unity配置Android ...

  10. linux驱动由浅入深系列:高通sensor架构实例分析之三(adsp上报数据详解、校准流程详解)【转】

    本文转载自:https://blog.csdn.net/radianceblau/article/details/76180915 本系列导航: linux驱动由浅入深系列:高通sensor架构实例分 ...

随机推荐

  1. Windows Azure Cloud Service (10) Role的生命周期

    <Windows Azure Platform 系列文章目录> 在上一章内容中,我们提到了Windows Azure会依次调用角色(Role)实例的OnStart()方法和Run()方法. ...

  2. nodejs学习笔记二——链接mongodb

    a.安装mongoose库用来链接mongodb数据库 安装mongodb数据库参考mongodb安装 前言(怨言) 本来是想安装mongodb库来链接mongodb的,命令行到nodejs工程目录: ...

  3. JVM之类加载器中篇

    先看一段代码吧! package com.tfdd.test; /** * @desc * @author chenqm * @date 2016年2月15日 */ public class Fina ...

  4. CSS魔法堂:你真的理解z-index吗?

    一.前言 假如只是开发简单的弹窗效果,懂得通过z-index来调整元素间的层叠关系就够了.但要将多个弹窗间层叠关系给处理好,那么充分理解z-index背后的原理及兼容性问题就是必要的知识储备了.本文作 ...

  5. PhotoKit框架介绍及使用

    PhotoKit 是一套比 AssetsLibrary 更新更完整也更高效的ios照片处理库,对资源的处理跟 AssetsLibrary 有很大的不同.下面简单介绍下PhotoKit的几个基本概念 P ...

  6. AppleScript的字典怎么看怎么用

    新迭代之前忙里偷闲摸鱼了几种脚本的写法:bash, alfred,automator,applescript 这篇就说说这个applescript 以iterm为例 初看它的字典大概长这样: 1.方法 ...

  7. [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(4)

    这个系列已经写了6篇,链接地址如下: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Auto ...

  8. js中的正则表达式使用

    function myValid() { var errorMsg = ""; var res = true; //拿到要验证的值. var receiveName = $(&qu ...

  9. 使用NuGet打包并发布至ProGet过程 (步骤详细,附python脚本)【上篇】

    一.基本知识 (1)NuGet : NuGet是一个为大家所熟知的Visual Studio扩展,通过这个扩展,开发人员可以非常方便地在Visual Studio中安装或更新项目中所需要的第三方组件, ...

  10. 图的存储及遍历 深度遍历和广度遍历 C++代码实现

    /*图的存储及遍历*/ #include<iostream> using namespace std; //----------------------------------- //邻接 ...