转载:http://blog.csdn.net/yanyan19880509/article/details/52349056

前言

前面介绍了ReentrantLock,又叫排他锁,本篇主要通过CountDownLatch的学习来了解Java并发包中是如何实现共享锁的。

CountDownLatch使用解说

CountDownLatch是java5中新增的一个并发工具类,其使用非常简单,下面通过伪代码简单看一下使用方式:

这是一个使用CountDownLatch非常简单的例子,创建的时候,需要指定一个初始状态值,本例为2,主线程调用 latch.await时,除非latch状态值为0,否则会一直阻塞休眠。当所有任务执行完后,主线程唤醒,最终执行打印动作。

以上只是一个最简单的例子,接着咱们再来看一个,这回,咱们想要在任务执行完后做更多的事情,如下图所示:

这一次,在线程3和线程4中,分别调用了latch.await(),当latch状态值为0时,这两个线程将会继续执行任务,但是顺序性是无法保证的。

CountDownLatch的方便之处在于,你可以在一个线程中使用,也可以在多个线程上使用,一切只依据状态值,这样便不会受限于任何的场景。

java共享锁模型

在java5提供的并发包下,有一个AbstractQueuedSynchronizer抽象类,也叫AQS,此类根据大部分并发共性作了一些抽象,便于开发者实现如排他锁,共享锁,条件等待等更高级的业务功能。它通过使用CAS和队列模型,出色的完成了抽象任务,在此向Doug Lea致敬。

AQS比较抽象,并且是优化精简的代码,如果一头扎进去,可能会比较容易迷失。本篇只解说CountDownLatch中使用到的共享锁模型。

我们以CountDownLatch第二个例子作为案例来分析一下,一开始,我们创建了一个CountDownLatch实例,

此时,AQS中,状态值state=2,对于 CountDownLatch 来说,state=2表示所有调用await方法的线程都应该阻塞,等到同一个latch被调用两次countDown后才能唤醒沉睡的线程。接着线程3和线程4执行了 await方法,这会的状态图如下:

注意,上面的通知状态是节点的属性,表示该节点出队后,必须唤醒其后续的节点线程。当线程1和线程2分别执行完latch.countDown方法后,会把state值置为0,此时,通过CAS成功置为0的那个线程将会同时承担起唤醒队列中第一个节点线程的任务,从上图可以看出,第一个节点即为线程3,当线程3恢复执行之后,其发现状态值为通知状态,所以会唤醒后续节点,即线程4节点,然后线程3继续做自己的事情,到这里,线程3和线程4都已经被唤醒,CountDownLatch功成身退。

上面的流程,如果落实到代码,把 state置为0的那个线程,会判断head指向节点的状态,如果为通知状态,则唤醒后续节点,即线程3节点,然后head指向线程3节点,head指向的旧节点会被删除掉。当线程3恢复执行后,发现自身为通知状态,又会把head指向线程4节点,然后删除自身节点,并唤醒 
线程4。

这里可能读者会有个疑问,线程节点的状态是什么时候设置上去的。其实,一个线程在阻塞之前,就会把它前面的节点设置为通知状态,这样便可以实现链式唤醒机制了。

CountDownLatch的原理学习的更多相关文章

  1. IIS原理学习

    IIS 原理学习 首先声明以下内容是我在网上搜索后整理的,在此只是进行记录,以备往后查阅只用. IIS 5.x介绍 IIS 5.x一个显著的特征就是Web Server和真正的ASP.NET Appl ...

  2. zookkeper原理学习

    zookkeper原理学习  https://segmentfault.com/a/1190000014479433   https://www.cnblogs.com/felixzh/p/58692 ...

  3. GIS原理学习目录

    GIS原理学习目录 内容提要 本网络教程是教育部“新世纪网络课程建设工程”的实施课程.系统扼要地阐述地理信息系统的技术体系,重点突出地理信息系统的基本技术及方法. 本网络教程共分八章:第一章绪论,重点 ...

  4. 转:SVM与SVR支持向量机原理学习与思考(一)

    SVM与SVR支持向量机原理学习与思考(一) 转:http://tonysh-thu.blogspot.com/2009/07/svmsvr.html 弱弱的看了看老掉牙的支持向量机(Support ...

  5. Android自复制传播APP原理学习(翻译)

     Android自复制传播APP原理学习(翻译) 1 背景介绍 论文链接:http://arxiv.org/abs/1511.00444 项目地址:https://github.com/Tribler ...

  6. 计算机原理学习(1)-- 冯诺依曼体系和CPU工作原理

    前言 对于我们80后来说,最早接触计算机应该是在95年左右,那个时候最流行的一个词语是多媒体. 依旧记得当时在同学家看同学输入几个DOS命令就成功的打开了一个游戏,当时实在是佩服的五体投地.因为对我来 ...

  7. Dubbo原理学习

    Dubbo源码及原理学习 阿里中间件团队博客 Dubbo官网 Dubbo源码解析 Dubbo源码解析-掘金 Dubbo源码解析-赵计刚 Dubbo系列 源码总结+最近感悟

  8. XGBoost原理学习总结

    XGBoost原理学习总结 前言 ​ XGBoost是一个上限提别高的机器学习算法,和Adaboost.GBDT等都属于Boosting类集成算法.虽然现在深度学习算法大行其道,但很多数据量往往没有太 ...

  9. Git原理学习记录

    Git原理学习记录 1.git init git-test ​ git init 实际上就是在特定的目录下创建对应的目录和文件 2.object $ echo "V1" > ...

随机推荐

  1. Java基础(34):Java中基本数据类型的包装类(主要为了不同数据类型之间更方便的进行转换)(Wrapper类)

    相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等.基本数据类型是不具备对象的特性的,比如基本类型不能调用方法.功能简单...,为了让基本数 ...

  2. C++之路进阶——bzoj1030(文本生成器)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在 ...

  3. bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race

    两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...

  4. Java泛型01--任意数组中两元素交换

    package com.zl.generic; /** * 交换“任意”数组 中两个元素 */ public class GenericSwapArray { public static void m ...

  5. paper 87:行人检测资源(下)代码数据【转载,以后使用】

    这是行人检测相关资源的第二部分:源码和数据集.考虑到实际应用的实时性要求,源码主要是C/C++的.源码和数据集的网址,经过测试都可访问,并注明了这些网址最后更新的日期,供学习和研究进行参考.(欢迎补充 ...

  6. oracle 的索引

    一.索引分类      按逻辑分: 单列索引(Single column):  单列索引是基于单列所创建的索引 复合(多列)索引(Concatenated ): 复合索引是基于两列或者多列所创建的索引 ...

  7. 深入了解webservice_概念总结

    最近公司需要对java web端的第三方接口进行测试,使用WebService+TestNG实现,TsetNg是常用的自动化测试框架,这就不介绍了. WebService是一种跨编程语言和跨操作系统平 ...

  8. Hadoop :map+shuffle+reduce和YARN笔记分享

    今天做了一个hadoop分享,总结下来,包括mapreduce,及shuffle深度讲解,还有YARN框架的详细说明等. v\:* {behavior:url(#default#VML);} o\:* ...

  9. 关于jQuery的bind()\trigger()\triggerHandler()

    1.bind() 事件绑定. 多个事件会链式累加,而不会覆盖. 即 $("div").bind("click",funtion(){alert("te ...

  10. Delphi Xe 中如何把日期格式统一处理,玩转 TDatetime

    日期格式的处理总是会很复杂,因为不同的环境日 期格式也不一样.为了程序统一处理,  最好把格式给统一了: 可以在程序的初始化段: FormatSettings.ShortDateFormat := ' ...