在CLH锁核心思想的影响下,JDK并发包以CLH锁作为基础而设计,其中主要是考虑到CLH锁更容易实现取消与超时功能。比起原来的CLH锁已经做了很大的改造,主要从两方面进行了改造:节点的结构与节点等待机制。在结构上引入了头结点和尾节点,他们分别指向队列的头和尾,尝试获取锁、入队列、释放锁等实现都与头尾节点相关,并且每个节点都引入前驱节点和后后续节点的引用;在等待机制上由原来的自旋改成阻塞唤醒。如图,通过前驱后续节点的引用一节节连接起来形成一个链表队列,对于头尾节点的更新必须是原子的。下面详细看看入队、检测挂起、释放出队、超时、取消等操作。

 

① 入队,整块逻辑其实是用一个无限循环进行CAS操作,即用自旋方式竞争直到成功。将尾节点tail的旧值赋予新节点node的前驱节点,并尝试CAS操作将新节点node赋予尾节点tail,原先的尾节点的后续节点指向新建节点node。完成上面步骤就建立起一条如图所示的链表队列。代码简化如下:

for (;;) {
   Node t = tail;
   node.prev = t;
   if (compareAndSetTail(t, node)) {
      t.next = node;
      return node;
   }
}

② 检测挂起,上面我们说到节点等待机制已经被JDK并发作者由自旋机制改造成阻塞机制,一个新建的节点完成入队操作后,如果是自旋则直接进入循环检测前驱节点是否为头结点即可,但现在被改为阻塞机制,当前线程将首先检测是否为头结点且尝试获取锁,如果当前节点为头结点并成功获取锁则直接返回,当前线程不进入阻塞,否则将当前线程阻塞。代码简化如下:

 for (;;) {
    if (node.prev == head)
if(尝试获取锁成功){
         head=node;
         node.next=null;
         return;
     }
   阻塞线程
}

③ 释放出队,出队的主要工作是负责唤醒等待队列中后续节点,让所有等待节点环环相接,每条线程有序地往下执行。代码简化如下:
Node s = node.next;
唤醒节点s包含的线程
④ 超时,在支持超时的模式下需要LockSupport类的parkNanos方法支持,线程在阻塞一段时间后会自动唤醒,每次循环将累加消耗时间,当总消耗时间大于等于自定义的超时时间时就直接分返。代码简化如下:

for (;;) {
   尝试获取锁
   if (nanosTimeout <= 总消耗时间)
      return;
   LockSupport.parkNanos(this, nanosTimeout);
 }

⑤ 取消,队列中等待锁的队列可能因为中断或超时而涉及到取消操作,这种情况下被取消的节点不再进行锁竞争。此过程主要完成的工作是将取消的节点移除,先将节点的。先将节点node状态设置成取消,再将前驱节点pred的后续节点指向node的后续节点,这里由于涉及到竞争,必须通过CAS进行操作,CAS操作就算失败也不必理会,因为已经改了节点的状态,在尝试获取锁操作中会循环对节点的状态判断。

node.waitStatus = Node.CANCELLED;
Node pred = node.prev;
Node predNext = pred.next;
Node next = node.next;
compareAndSetNext(pred, predNext, next);

喜欢研究java的同学可以交个朋友:

从JDK源码角度看并发锁的优化的更多相关文章

  1. 从JDK源码角度看并发竞争的超时

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

  2. 从JDK源码角度看Short

    概况 Java的Short类主要的作用就是对基本类型short进行封装,提供了一些处理short类型的方法,比如short到String类型的转换方法或String类型到short类型的转换方法,当然 ...

  3. 从JDK源码角度看Byte

    Java的Byte类主要的作用就是对基本类型byte进行封装,提供了一些处理byte类型的方法,比如byte到String类型的转换方法或String类型到byte类型的转换方法,当然也包含与其他类型 ...

  4. 从JDK源码角度看Object

    Java的Object是所有其他类的父类,从继承的层次来看它就是最顶层根,所以它也是唯一一个没有父类的类.它包含了对象常用的一些方法,比如getClass.hashCode.equals.clone. ...

  5. 从JDK源码角度看Boolean

    Java的Boolean类主要作用就是对基本类型boolean进行封装,提供了一些处理boolean类型的方法,比如String类型和boolean类型的转换. 主要实现源码如下: public fi ...

  6. 从JDK源码角度看java并发的公平性

    JAVA为简化开发者开发提供了很多并发的工具,包括各种同步器,有了JDK我们只要学会简单使用类API即可.但这并不意味着不需要探索其具体的实现机制,本文从JDK源码角度简单讲讲并发时线程竞争的公平性. ...

  7. 从JDK源码角度看java并发的原子性如何保证

    JDK源码中,在研究AQS框架时,会发现很多地方都使用了CAS操作,在并发实现中CAS操作必须具备原子性,而且是硬件级别的原子性,java被隔离在硬件之上,明显力不从心,这时为了能直接操作操作系统层面 ...

  8. 从JDK源码角度看java并发线程的中断

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

  9. 从JDK源码角度看线程池原理

    "池"技术对我们来说是非常熟悉的一个概念,它的引入是为了在某些场景下提高系统某些关键节点性能,最典型的例子就是数据库连接池,JDBC是一种服务供应接口(SPI),具体的数据库连接实 ...

随机推荐

  1. jquery checkbox是否选中

    $("#chkDisplayZxOnly").is(":checked")  选中返回true,否则返回false

  2. ZH奶酪:Ionic中(弹出式窗口)的$ionicModal使用方法

    Ionic中[弹出式窗口]有两种(如下图所示),$ionicModal和$ionicPopup; $ionicModal是完整的页面: $ionicPopup是(Dialog)对话框样式的,直接用Ja ...

  3. Ubuntu14.04安装 HP DeskJet GT 5820 打印机的方法

    原创内容发表在 http://www.linuxdiyf.com/linux/25331.html 步骤就是: 这里(https://sourceforge.net/projects/hplip/fi ...

  4. String字符串的操作

    字符串的常用操作 # Author:nadech name = "my name is nadech" print(name.count("a")) print ...

  5. JUnit单元测试教程(翻译自Java Code Geeks)

    JUnit单元测试教程--终极指南 JUnit单元测试教程终极指南 说明 单元测试简介 1 什么是单元测试 2 测试覆盖 3 Java中的单元测试 JUnit简介 1 使用Eclipse实现简单JUn ...

  6. Mac OS: How to keep network connection alive after sleep

    Do the following: Find out what the network interface is for your wifi. Mine is "en1" for ...

  7. Hibernate之综合问题

    n + 1问题 query.iterate()方式返回迭代查询会开始发出一条语句:查询所有记录ID语句 Hibernate: select student0_.id ascol_0_0_from t_ ...

  8. RxJava(二) map操作符用法详解

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51531348 本文出自:[余志强的博客] 1 map操作符的作用 R ...

  9. Centos6.5 mysql安装

    cenos中安装软件使用yum进行安装,小米加步枪不如ak47. 第1步.yum安装mysql   yum -y install mysql-server 第2步.设置开机启动   chkconfig ...

  10. springmvc的介绍和第一个例子

    SpringMVC是Spring 框架自带的一部分. SpringMVC底层基于:Servlet Struts2底层基于:filter struts1底层基于:Servlet spring 各模块 我 ...