根据前面的线程阻塞与唤醒小节知道,目前在Java语言层面能实现阻塞唤醒的方式一共有三种:suspend与resume组合、wait与notify组合、park与unpark组合。其中suspend与resume因为存在无法解决的竟态问题而被Java废弃,同样,wait与notify也存在竟态条件,wait必须在notify之前执行,假如一个线程先执行notify再执行wait将可能导致一个线程永远阻塞,如此一来,必须要提出另外一种解决方案,就是park与unpark组合,它位于juc包下,应该也是因为当时编写juc时发现java现有方式无法解决问题而引入的新阻塞唤醒方式,由于park与unpark使用的是许可机制,许可最大为1,所以unpark与park操作不会累加,而且unpark可以在park之前执行,如unpark先执行,后面park将不阻塞。

Java真正意义上的语言层面上的并发编程应该从并发专家Doug Lea领导的JSR-166开始,此规范请求向JCP提交了向Java语言中添加并发编程工具,即在jdk中添加java.util.concurrent工具包供开发者使用,开发者可以轻松构建自己的同步器,而在此之前并发过程中同步都只能依靠JVM内置的管程。
ASQ框架的阻塞和唤醒显然使用的是LockSupport类的park与unpark方法,分别调用的是Unsafe类的park与unpark本地方法。逻辑如下:
阻塞
if(尝试获取锁失败) {
    创建node
    使用CAS方式把node插入到队列尾部
    while(true){
    if(尝试获取锁成功 并且 node的前驱节点为头节点){
把当前节点设置为头节点
    跳出循环
}else{
    使用CAS方式修改node前驱节点的waitStatus标识为signal
    if(修改成功){
        LockSupport.park();
}
}
唤醒
if(尝试释放锁成功){
LockSupport.unpark(下一节点包含的线程);
}
假如一条线程参与锁竞争,首先先尝试获取锁,失败的话创建节点并插入队列尾部,然后再次尝试获取锁,如若成功则不做其他任务处理直接返回,否则设置节点状态为待运行状态,最后使用LockSupport的park阻塞当前线程。前驱节点运行完后将尝试唤醒后继节点,使用的即是LockSupport的unpark唤醒。
总的来说,java提供的juc并发工具包,在阻塞与唤醒操作方面由于suspend与resume存在各种各样问题,必须使用LockSupport中提供的方法操作。

喜欢研究java的同学可以交个朋友,下面是本人的微信号:


Java并发框架——AQS之阻塞与唤醒的更多相关文章

  1. 深入理解Java并发框架AQS系列(一):线程

    深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 一.概述 1.1.前言 重剑无锋,大巧不工 读j.u.c包下的源码,永远无法绕开的经典 ...

  2. 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念

    深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 一.AQS框架简介 AQS诞生于Jdk1.5,在当时低效且功能单一的synchroni ...

  3. 深入理解Java并发框架AQS系列(四):共享锁(Shared Lock)

    深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 深入理解Java并发框架AQS系列(三):独占锁(Exclusive Lock) 深入 ...

  4. Java并发框架——AQS阻塞队列管理(三)——CLH锁改造

    在CLH锁核心思想的影响下,Java并发包的基础框架AQS以CLH锁作为基础而设计,其中主要是考虑到CLH锁更容易实现取消与超时功能.比起原来的CLH锁已经做了很大的改造,主要从两方面进行了改造:节点 ...

  5. 深入理解Java并发框架AQS系列(三):独占锁(Exclusive Lock)

    一.前言 优秀的源码就在那里 经过了前面两章的铺垫,终于要切入正题了,本章也是整个AQS的核心之一 从本章开始,我们要精读AQS源码,在欣赏它的同时也要学会质疑它.当然本文不会带着大家逐行过源码(会有 ...

  6. Java并发框架——AQS超时机制

    AQS框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待以提高性 ...

  7. Java并发框架——AQS阻塞队列管理(一)——自旋锁

    我们知道一个线程在尝试获取锁失败后将被阻塞并加入等待队列中,它是一个怎样的队列?又是如何管理此队列?这节聊聊CHL Node FIFO队列. 在谈到CHL Node FIFO队列之前,我们先分析这种队 ...

  8. Java并发框架——AQS阻塞队列管理(二)——自旋锁优化

    看Craig, Landin, and Hagersten发明的CLH锁如何优化同步带来的花销,其核心思想是:通过一定手段将所有线程对某一共享变量轮询竞争转化为一个线程队列且队列中的线程各自轮询自己的 ...

  9. Java并发框架——AQS中断的支持

    线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...

随机推荐

  1. [SDOI2016]生成魔咒

    题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例如 S=[1, ...

  2. Linux查看Tomcat是否多次重启命令

    1.查看命令 ps -ef|grep apache-tomcat-9090|grep -v grep|awk '{print $2}' 如果存在两个端口则多次重启, 2.停掉命令: kill -9  ...

  3. TeamForge使用指南

    1.什么是TeamForge 可以把TeamForge简单的理解为另外一种github 2.TeamForge的地址 与Project有关,一般会有明确的Link 3.TeamForge登录 用户名和 ...

  4. C语言实现的排序

    冒泡排序 比较相邻的两个元素,若顺序不对,则将其调换 通过一遍排序,较大的数会排到最后(沉到底部) 两层循环,外层循环控制遍数,内层循环控制每一遍内的排序. 完整代码: #include<std ...

  5. Java HttpClient伪造请求之简易封装满足HTTP以及HTTPS请求

    HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 jav ...

  6. Linux的管理类命令及其使用方法

    文件操作相关有一些命令可以帮助我们"修剪"之前看到的文件树. $touch a.txt 如果a.txt不存在,生成一个新的空文档a.txt.如果a.txt存在,那么只更改该文档的时 ...

  7. spark升级后 集成hbase-1.0.0-cdh5.4.5异常

    .具体场景如下: spark1.6  升级  spark2.2 后    分析查询hbase  数据报异常: 具体错误如下:       ERROR TableInputFormat: java.io ...

  8. centos6 安装redis-4.0.9

    从redis官网下载Linux redis4.0.9版本,我下载的redis-4.0.9.tar.gz(目前最新稳定版),下载到/usr/local/src目录,如果没有就mkdir创建一个. 下载链 ...

  9. python基础学习(一)

    python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum),诞生时间1989年圣诞 一.变量的命令规则 1.变量只能由大小写字母.数字和下划线三部分组成,并且不能以数字 ...

  10. Linux下常用的配置

    本文主要给出的都是一些常用的Linux配置,系统版本是基于CentOs6.3,供自己复习和新人学习,不当之处还请指正. vmware tools安装 虚拟机--->安装vmware tools ...