Java多线程闲聊(五):AQS


前言

今天的第二篇了,我肚子里也没有那么多的墨水,所以这第二篇的前言,就免了吧。


正文

AQS,AbstractQueueSynchronizer,是Java官方所提供的一种同步机制。

如果说让我逐行来讲每行代码到底说了些什么,我想其实真的可能今天晚上我不用睡觉了。所以作为资深的懒人,还是按照我一贯的思路,讲讲整体的思路吧。

首先AQS继承自AbstractOwnableSynchronizer,后面简称AOS,这个类的作用就是简单地定义一种排他的线程同步机制,而并没有实现。然后AQS则是希望基于CAS机制和模板方法设计模式来构建一个基于CLH队列锁的同步框架。

OK,出现了三个全新的名词,我们逐个来讲讲清楚。

首先是CAS机制,那么什么是CAS机制?众所周知,java相对稳定的同步机制就是synchronized了,但是我之前说过,该关键字其实过于暴力,当一个线程拿到了锁,那么另外尝试拿锁的线程就会进入阻塞状态,知道锁被释放了才会被唤醒。

AQS类中最核心的一个成员变量就是int volatile state,这个变量表示了当前AQS的状态,当同步器被占有时,该变量大于0,否则等于0。为什么需要用volatile来进行修饰呢?且听我细细说来,使用AQS进行同步操作的可能有多个线程。这些线程通过acquire()方法来进行锁的获取,如何获取锁呢?往往首先通过CAS乐观锁机制来尝试获取锁,如果获取不到才会用悲观锁的机制把它塞进同步队列慢慢熬,关于同步队列,我在系列的第六篇博客里有说明,这里就不赘述了。

然后就是在设计AQS的时候,还设计了一种所谓的共享模式。根据是不是共享模式衍生出了所谓的共享锁和排他锁。那么共享锁是什么呢?一种常见的使用就是对于读写所加的锁。我们在尝试用多线程对数据进行读的操作,往往就不用担心对数据的篡改,所以在读的时候就算要加锁,也只需要加共享锁就行了。唯独,如果是在多线程同时需要进行写的操作的时候,就需要添加排他锁了,因为JMM模型中将内存分为工作内存和主内存的原因。


问题

  1. tryAcquire和tryAcquireShared的区别?
    AbstractQueuedSynchronizer(aqs)中acquireShared和releaseShared的理解_a6822342的博客-CSDN博客
  2. 什么是模板方法设计模式?
  3. 如何定义空实现?
  4. Lock.park()实现原理?
  5. 公平锁和非公平锁的区别?为什么可重入锁ReentranceLock默认是非公平锁?
  6. 如何自实现可重入锁?

Java多线程闲聊(五):AQS相关推荐

  1. Java多线程闲聊(六):synchronized关键字

    Java多线程闲聊(六):synchronized关键字 前言 这篇文章我会在博客置顶,为什么呢?因为,三篇引用的文章写得太好了,我害怕后面找不到,看不到,然后忘了! 让我想想,感觉昨天的前言把最近肚 ...

  2. Java多线程闲聊(四):阻塞队列与线程池原理

    Java多线程闲聊(四)-阻塞队列与线程池原理 前言 复用永远是人们永恒的主题,这能让我们更好地避免重复制造轮子. 说到多线程,果然还是绕不开线程池,那就来聊聊吧. 人们往往相信,世界是存在一些规律的 ...

  3. Java多线程闲聊(二):活锁和死锁

    Java多线程闲聊(二):活锁和死锁 这两个情况其实都是应该需要避免的情况,为了便于自己的回顾,我还是希望通过尽可能简单的表达来进行简要的归纳. 何谓死锁,就是正正紧紧按照Java的规范进行编程依然会 ...

  4. Java多线程闲聊(三):RxJava

    多线程闲聊(三) 作为一名Android开发工程师,我对于RxJava还是比较熟悉的.或者说,如果让我凭空开发出类似RxJava的效果,说真的,我感觉我真的可以!在这里我推荐一本相关介绍函数式编程的相 ...

  5. Java多线程系列(五):线程池的实现原理、优点与风险、以及四种线程池实现

    为什么需要线程池 我们有两种常见的创建线程的方法,一种是继承Thread类,一种是实现Runnable的接口,Thread类其实也是实现了Runnable接口.但是我们创建这两种线程在运行结束后都会被 ...

  6. Java多线程(五)之BlockingQueue深入分析

    一.概述: BlockingQueue作为线程容器,可以为线程同步提供有力的保障. 二.BlockingQueue定义的常用方法 1.BlockingQueue定义的常用方法如下:   抛出异常 特殊 ...

  7. Java多线程闲聊(一):概论

    其实我对Java有较高的好感度已经是很久之前的事情, 因为Java是第一门让我感觉很有成就感的语言.想想那些青葱岁月,走出过去已经让我花了太多太多的时间,我想说的是,今后,我要努力让自己面向未来. 很 ...

  8. java多线程总结五:线程池的原理及实现

    1.线程池简介:     多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.         假设一个服务器完成一项任务所需时间为:T1 ...

  9. Java多线程(五)——多线程的多线程池

    目录 一.引言 二.多线程池种类 三.多线程池实现 四.总结 一.引言 我们可以创建多线程了为什么要用多线程池? 服务器在创建和销毁线程上花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用 ...

最新文章

  1. [bzoj1042][HAOI2008]硬币购物
  2. 深度强化学习的前景:帮助机器掌控复杂性
  3. python scrapy框架基如何实现多线程_【转】爬虫的一般方法、异步、并发与框架scrapy的效率比较...
  4. 从零开始学视觉Transformer(6):Swin Transformer-1
  5. 作者:周涛(1979-),男,博士,启明星辰教授级高级工程师、大数据实验室副主任。...
  6. Oracle truncate和delete的区别
  7. 无心剑中译雪莱诗14首
  8. 一个空值_3秒快速、大批量删除或修改Excel中的空值 | 学术小课堂
  9. BiLSTM+CRF命名实体识别:达观杯败走记(下篇)
  10. 《Redis视频教程》(p7)
  11. react 使用iconfont 图标
  12. PackageManager使用详解
  13. 恒生电子 招聘FPGA开发/验证工程师
  14. 大数据技术基础学习总结
  15. 「CF230A」龙的战争(详细分析)
  16. 如何把win桌面的压缩包复制到虚拟机共享文件夹中
  17. C语言——将数字和数字字符输入给char型变量会如何?
  18. beego框架-logs模块学习笔记
  19. 嵌入式linux编程过成中模块从串口读数需要特定的字符段并且需要每两位字符数组元素转换成一个16进制数(提取特定字符串+字符串转16进制)
  20. Druid学习笔记(2)Druid架构剖析

热门文章

  1. php nginx exec失败,小白问题:用nginx配置php后nginx无法启动。
  2. 如何在vim保存时获得sudo权限
  3. jquery实现上下左右键盘监听_python 使用pygame工具包实现贪吃蛇游戏(多彩版)
  4. html img 指定旋转角度_ALLEN老师自动化测试小课堂 | 生成HTML可视化报告的两个常见模块...
  5. 计算机网络大一上学期期末考试试题及答案,大一第一学期期末计算机考试题及答案)...
  6. vscode更改安装路径 无法访问_装完系统必做的优化,更改用户文件和软件安装默认路径,你知道吗...
  7. python优化算法工具包_这可能是史上最全的 Python 算法集(建议收藏)
  8. docker linux界面版,centos 7 Docker使用Portainer搭建可视化界面
  9. 福建2020年3月计算机二级报名时间,福建2020年3月计算机等级考试报名时间
  10. PHPExcel报错:谷歌浏览器显示网页可能暂时无法连接,或者它已永久性地移动到了新网址的原因?