本文转载自公众号: Java技术驿站

Java的内置锁一直都是备受争议的,在JDK 1.6之前,synchronized这个重量级锁其性能一直都是较为低下,虽然在1.6后,进行大量的锁优化策略(死磕Java并发:深入分析synchronized的实现原理),但是与Lock相比synchronized还是存在一些缺陷的:虽然synchronized提供了便捷性的隐式获取锁释放锁机制(基于JVM机制),但是它却缺少了获取锁与释放锁的可操作性,可中断、超时获取锁,且它为独占式在高并发场景下性能大打折扣。

在介绍Lock之前,我们需要先熟悉一个非常重要的组件,掌握了该组件JUC包,下面很多问题都不在是问题了。

该组件就是AQS。

AQS,AbstractQueuedSynchronizer,即队列同步器。它是构建锁或者其他同步组件的基础框架(如ReentrantLock、ReentrantReadWriteLock、Semaphore等),JUC并发包的作者(Doug Lea)期望它能够成为实现大部分同步需求的基础。它是JUC并发包中的核心基础组件。

AQS解决了实现同步器时涉及当的大量细节问题,例如获取同步状态、FIFO同步队列。基于AQS来构建同步器可以带来很多好处,它不仅能够极大地减少实现工作,而且也不必处理在多个位置上发生的竞争问题。

在基于AQS构建的同步器中,只能在一个时刻发生阻塞,从而降低上下文切换的开销,提高了吞吐量。同时在设计AQS时充分考虑了可伸缩行,因此J.U.C中所有基于AQS构建的同步器均可以获得这个优势。

AQS的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状态。

AQS使用一个int类型的成员变量state来表示同步状态,当state>0时表示已经获取了锁,当state = 0时表示释放了锁。它提供了三个方法(getState()、setState(int newState)、compareAndSetState(int expect,int update))来对同步状态state进行操作,当然AQS可以确保对state的操作是安全的。

AQS通过内置的FIFO同步队列来完成资源获取线程的排队工作,如果当前线程获取同步状态失败(锁)时,AQS则会将当前线程以及等待状态等信息构造成一个节点(Node)并将其加入同步队列,同时会阻塞当前线程,当同步状态释放时,则会把节点中的线程唤醒,使其再次尝试获取同步状态。

AQS主要提供了如下一些方法:

  1. getState():返回同步状态的当前值;

  2. setState(int newState):设置当前同步状态;

  3. compareAndSetState(int expect, int update):使用CAS设置当前状态,该方法能够保证状态设置的原子性;

  4. tryAcquire(int arg):独占式获取同步状态,获取同步状态成功后,其他线程需要等待该线程释放同步状态才能获取同步状态;

  5. tryRelease(int arg):独占式释放同步状态;

  6. tryAcquireShared(int arg):共享式获取同步状态,返回值大于等于0则表示获取成功,否则获取失败;

  7. tryReleaseShared(int arg):共享式释放同步状态;

  8. isHeldExclusively():当前同步器是否在独占式模式下被线程占用,一般该方法表示是否被当前线程所独占;

  9. acquire(int arg):独占式获取同步状态,如果当前线程获取同步状态成功,则由该方法返回,否则,将会进入同步队列等待,该方法将会调用可重写的tryAcquire(int arg)方法;

  10. acquireInterruptibly(int arg):与acquire(int arg)相同,但是该方法响应中断,当前线程为获取到同步状态而进入到同步队列中,如果当前线程被中断,则该方法会抛出InterruptedException异常并返回;

  11. tryAcquireNanos(int arg,long nanos):超时获取同步状态,如果当前线程在nanos时间内没有获取到同步状态,那么将会返回false,已经获取则返回true;

  12. acquireShared(int arg):共享式获取同步状态,如果当前线程未获取到同步状态,将会进入同步队列等待,与独占式的主要区别是在同一时刻可以有多个线程获取到同步状态;

  13. acquireSharedInterruptibly(int arg):共享式获取同步状态,响应中断;

  14. tryAcquireSharedNanos(int arg, long nanosTimeout):共享式获取同步状态,增加超时限制;

  15. release(int arg):独占式释放同步状态,该方法会在释放同步状态之后,将同步队列中第一个节点包含的线程唤醒;

  16. releaseShared(int arg):共享式释放同步状态;

后面LZ将会就CLH队列,同步状态的获取、释放做详细介绍。

- END -

 往期推荐:

  • 死磕Java系列:

  1. 深入分析ThreadLocal

  2. 深入分析synchronized的实现原理

  3. 深入分析volatile的实现原理

  4. Java内存模型之happens-before

  5. Java内存模型之重排序

  6. Java内存模型之分析volatile

  7. Java内存模型之总结

……

  • Spring系列:

  1. Spring Cloud Zuul中使用Swagger汇总API接口文档

  2. Spring Cloud Config Server迁移节点或容器化带来的问题

  3. Spring Cloud Config对特殊字符加密的处理

  4. Spring Boot使用@Async实现异步调用:使用Future以及定义超时

  5. Spring Cloud构建微服务架构:分布式配置中心(加密解密)

  6. Spring Boot快速开发利器:Spring Boot CLI

……

号外:

最近在做几个有意思的开源项目,感兴趣的朋友可以看看。

地址:

https://github.com/dyc87112/swagger-butler

可关注我的公众号

深入交流、更多福利

扫码加入我的知识星球


点击“阅读原文”,看本号其他精彩内容

死磕Java并发:J.U.C之AQS简介相关推荐

  1. 死磕Java并发:J.U.C之并发工具类:CountDownLatch

    作者:chenssy 来源:Java技术驿站 在上篇博客中介绍了Java四大并发工具一直的CyclicBarrier,今天要介绍的CountDownLatch与CyclicBarrier有点儿相似. ...

  2. 死磕Java并发:J.U.C之AQS:CLH同步队列

    本文转载自公号:Java技术驿站 在上篇文章"死磕Java并发:J.U.C之AQS简介"中提到了AQS内部维护着一个FIFO队列,该队列就是CLH同步队列. CLH同步队列是一个F ...

  3. 【死磕Java并发】-----J.U.C之AQS:CLH同步队列

    原文出处:https://www.cmsblogs.com/category/1391296887813967872 『chenssy』 在上篇博客[死磕Java并发]-----J.U.C之AQS:A ...

  4. 死磕Java并发:Java内存模型之分析volatile

    近期活动:加班的你,需要一束光 本文转载自公众号: Java技术驿站 前篇文章<死磕Java并发:深入分析volatile的实现原理>中已经阐述了volatile的特性了: volatil ...

  5. 死磕Java并发:Java内存模型之happens-before

    本文转载自公众号: Java技术驿站 在上篇<死磕Java并发:深入分析volatile的实现原理>中提到过由于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的 ...

  6. 【死磕Java并发】-----Java内存模型之happens-before

    在上篇博客([死磕Java并发]-–深入分析volatile的实现原理)LZ提到过由于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的问题.那么我们正确使用同步.锁的情况下 ...

  7. 【死磕Java并发】----- 死磕 Java 并发精品合集

    原文出处:https://www.cmsblogs.com/category/1391296887813967872 『chenssy』 [死磕 Java 并发]系列是 LZ 在 2017 年写的第一 ...

  8. 死磕 Java 并发

    作者 :大明哥 博客 :http://cmsblogs.com/?cat=151 目录 : <[死磕 Java 并发]-– 深入分析 synchronized 的实现原理> <[死磕 ...

  9. 死磕Java并发:分析 ArrayBlockingQueue 构造函数加锁问题

    作者: chenssy 来源:Java技术驿站 昨天有位小伙伴问我一个 ArrayBlockingQueue 中的一个构造函数为何需要加锁,其实这个问题我还真没有注意过.主要是在看 ArrayBloc ...

最新文章

  1. 遮挡人脸检测--Detecting Masked Faces in the Wild with LLE-CNNs
  2. 第十六 届全国大学生智能汽车竞赛 讯飞创意组 全国 选拔赛 竞赛规则
  3. 卷积神经网络「失陷」,CoordConv来填坑
  4. 网络优化常见专业术语详解
  5. 计算机博士美国学校推荐,留学随笔:一位计算机博士留学美国的感悟
  6. Linux系统有线网络抓包程序
  7. Spring Security 用户登录实战
  8. SAP License:电子行业ERP实施
  9. 神经网络 demo(斯坦福)
  10. swagger 上传文件 参数_跟我一起学.NetCore之Swagger让前后端不再烦恼及界面自定义...
  11. 紫光输入法linux,紫光拼音输入法下载_紫光拼音输入法最新版下载-太平洋下载中心...
  12. 国税局发票查验API接口文档说明
  13. EA 2022 HSN Plugfest- UNH-IOL以太网联盟高速以太网插拔互操作性测试活动[多图] 400G/800G/112G PAM4
  14. 增长的旋律——AARRR模式思考(二)
  15. 一步步搭建自己的博客网站
  16. 读书笔记-《我的第一本算法书》
  17. `docker数据持久化volume和bind mounts两种方式
  18. 异常:EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
  19. 希望所有计算机专业同学都知道这些老师
  20. 基于Python实现图像相似度检测【100010088】

热门文章

  1. java 反序列化 ysoserial exploit/JRMPListener 原理剖析
  2. python pip 错误 ModuleNotFoundError: No module named pip._internal 解决办法
  3. mysql phpmyadmin 修改下一个自增值的开始位置 计数重置
  4. linux ubuntu debian apt-get报错 Unable to acquire the dpkg frontend lock 解决方法
  5. linux nDPI 协议检测 源码分析
  6. 使用OpenVas漏扫
  7. OPKG 软件包管理
  8. windbg 脚本命令实例
  9. 服务器被非法上传文件,DiscuzX没有合法的文件被上传的修复方法
  10. 按钮右对齐_9张图,学会Excel中的对齐技巧