在前面博客中,LZ讲到了ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch,他们都有各自获取锁的方法,同时相对于Java的内置锁,他们具有明显的优势:花最小的空间开销创建锁、最少的时间开销获得锁、使用更加方便灵活。

参考Java的内置锁,对于JUC同步器而言,他应该具备两个最基本的功能:获取锁,释放锁。其中获取锁应该是先判断当前状态是否可以获取,如果不可以获取则处于阻塞状态,释放应该是释放后修改状态,让其他线程能够得到该锁(唤醒其他线程),如下:

lock:while(state){ // getLock(); //获取锁

return currentThread; //返回当前线程

}

release:

updateState();//修改状态

notify other thread; //唤醒其他线程

我们知道,在JUC中,各个同步器获取锁和释放锁的方法都不相同,比如:lock.lock()、Semaphore.acquire()、 CountDownLatch.await()等等,假如他们都各自实现各自的方法,那么这个JUC框架顶多只能算一个中下等的框架设计了。这是AQS腾空出世,AQS作为一个核心的处理框架,他提供了大量的同步操作,同时用户还可以在此类的基础上进行自定义,实现自己的同步器。其主要框架如下:

从上图可以看出AQS是JUC同步器的基石。下面就AQS涉及的技术原理简单阐述下,以后会对其做详细的说明。

1、状态位state

AQS用的是一个32位的整型来表示同步状态的,它是用volatile修饰的:

private volatile int state;

在互斥锁中它表示着线程是否已经获取了锁,0未获取,1已经获取了,大于1表示重入数。同时AQS提供了getState()、setState()、compareAndSetState()方法来获取和修改该值:

protected final intgetState() {returnstate;

}protected final void setState(intnewState) {

state=newState;

}protected final boolean compareAndSetState(int expect, intupdate) {return unsafe.compareAndSwapInt(this, stateOffset, expect, update);

}

这些方法需要java.util.concurrent.atomic包的支持,采用CAS操作,保证其原则性和可见性。

2、CLH同步队列

在前面就提到过AQS内部维护着一个FIFO的CLH队列,所以AQS并不支持基于优先级的同步策略。至于为何要选择CLH队列,主要在于CLH锁相对于MSC锁,他更加容易处理cancel和timeout,同时他具备进出队列快、无所、畅通无阻、检查是否有线程在等待也非常容易(head != tail,头尾指针不同)。当然相对于原始的CLH队列锁,ASQ采用的是一种变种的CLH队列锁:

1、原始CLH使用的locked自旋,而AQS的CLH则是在每个node里面使用一个状态字段来控制阻塞,而不是自旋。

2、为了可以处理timeout和cancel操作,每个node维护一个指向前驱的指针。如果一个node的前驱被cancel,这个node可以前向移动使用前驱的状态字段。

3、head结点使用的是傀儡结点。

3、共享锁、互斥锁

在AQS维护的CLH队列锁中,每个节点(Node)代表着一个需要获取锁的线程。该Node中有两个常量SHARE、EXCLUSIVE。其中SHARE代表着共享模式,EXCLUSIVE代表着独占模式。

static final classNode {/**Marker to indicate a node is waiting in shared mode*/

static final Node SHARED = newNode();/**Marker to indicate a node is waiting in exclusive mode*/

static final Node EXCLUSIVE = null;/

}

其中共享模式是允许多个线程可以获取同一个锁,而独占模式则一个锁只能被一个线程持有,其他线程必须要等待。

4、阻塞、唤醒

我们知道在使用Java内置锁时,可以使用wait、notify方法来阻塞、唤醒线程,但是AQS并没有采用该模式,而是通过LockSupport.park() 和 LockSupport.unpark() 的本地方法来实现线程的阻塞和唤醒。

aqs clh java_【Java并发编程实战】----- AQS(一):简介相关推荐

  1. aqs clh java_【Java并发编程实战】—– AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...

  2. 视频教程-Java并发编程实战-Java

    Java并发编程实战 2018年以超过十倍的年业绩增长速度,从中高端IT技术在线教育行业中脱颖而出,成为在线教育领域一匹令人瞩目的黑马.咕泡学院以教学培养.职业规划为核心,旨在帮助学员提升技术技能,加 ...

  3. Java并发编程实战笔记2:对象的组合

    设计线程安全的类 在设计现车让安全类的过程之中,需要包含以下三步: 找出构成对象状态的所有变量 找出约束状态变量的不变性条件 建立对象状态的并发访问策略 实例封闭 通过封闭机制与合适的加锁策略结合起来 ...

  4. java 多线程缓存_[Java教程]【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列...

    [Java教程][JAVA并发编程实战]12.使用condition实现多线程下的有界缓存先进先出队列 0 2016-11-29 17:00:10 package cn.study.concurren ...

  5. Java并发编程实战————恢复中断

    中断是一种协作机制,一个线程不能强制其他线程停止正在执行的操作而去执行其他操作. 什么是中断状态? 线程类有一个描述自身是否被中断了的boolean类型的状态,可以通过调用 .isInterrupte ...

  6. Java并发编程实战————Executor框架与任务执行

    引言 本篇博客介绍通过"执行任务"的机制来设计应用程序时需要掌握的一些知识.所有的内容均提炼自<Java并发编程实战>中第六章的内容. 大多数并发应用程序都是围绕&qu ...

  7. Java并发编程实战————Semaphore信号量的使用浅析

    引言 本篇博客讲解<Java并发编程实战>中的同步工具类:信号量 的使用和理解. 从概念.含义入手,突出重点,配以代码实例及讲解,并以生活中的案例做类比加强记忆. 什么是信号量 Java中 ...

  8. Java并发编程实战_不愧是领军人物!这种等级的“Java并发编程宝典”谁能撰写?...

    前言 大家都知道并发编程技术就是在同一个处理器上同时的去处理多个任务,充分的利用到处理器的每个核心,最大化的发挥处理器的峰值性能,这样就可以避免我们因为性能而产生的一些问题. 大厂的核心负载肯定是非常 ...

  9. java并发编程实战学习(3)--基础构建模块

    转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put ...

  10. java单线程共享,「Java并发编程实战」之对象的共享

    前言 本系列博客是对<Java并发编程实战>的一点总结,本篇主要讲解以下几个内容,内容会比较枯燥.可能大家看标题不能能直观的感受出到底什么意思,这就是专业术语,哈哈,解释下,术语(term ...

最新文章

  1. matlab波的极化特性,Matlab GUI在电磁波极化特性教学中的应用
  2. 看漫画,学电子,我居然看懂了!
  3. php7中使用 xhprof 分析
  4. Python较为经典的53个Python库
  5. java dao 单元测试_Spring Service、Dao进行Junit单元测试
  6. 【剑指offer】面试题39:数组中出现次数超过一半的数字
  7. html异形轮播,异形滚动
  8. 车联网领域,传统TSP企业做错了什么 ?
  9. 米斯特白帽培训讲义(v2)漏洞篇 第三方风险
  10. 计算机硬件物理设备包含,计算机硬件
  11. 什么是PM2 ---- (零秒重启)
  12. halcon中的深度学习
  13. 计算机专业英语交换机,计算机专业英语词汇
  14. MT6573台开发分支下配置多个项目的规范说明_mi
  15. 服务器托管双线技术方案
  16. 启动计算机应用程序的命令,如何设置电脑Windows开机启动项命令?
  17. 深度学习网络基础——感受野
  18. 动圈耳机振膜_小白大讲堂: 耳机振膜材料对音质的影响
  19. RabbitMQ学习笔记:springboot2 amqp集成生产者消费者
  20. C#通过ip地址取当前城市

热门文章

  1. 高并发内存占用持续下降_师兄,为什么删除数据后,Redis内存占用依然很高?...
  2. android activity生命周期_Android岗高频面试题合一集,看你能答出几题?
  3. 浙江大学计算机学院研究生论文盲审,浙江理工大学研究生学位论文盲审实施办法...
  4. treeset java_Java TreeSet iterator()方法与示例
  5. javascript中Array的操作
  6. NPM使用前设置和升级
  7. 使用SharedPreferences存储和读取数据
  8. Ray集群搭建 Python Demo
  9. Win10安装 WSL Ubuntu Linux系统,非双系统,完美兼容超详细版本
  10. Tensorflow C3D完成视频动作识别