JDK并发工具类以及AQS组件

AQS介绍
AbstractQueuedSynchronizer,AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器。
AQS 原理
AQS维护一个共享资源state,通过内置的FIFO来完成获取资源线程的排队工作。(这个内置的同步队列称为"CLH"队列)。该队列由一个一个的Node结点组成,每个Node结点维护一个prev引用和next引用,分别指向自己的前驱和后继结点。AQS维护两个指针,分别指向队列头部head和尾部tail。
在这里插入图片描述
其实就是个双端双向链表。
AQS是JUC中很多同步组件的构建基础,简单来讲,它内部实现主要是状态变量state和一个FIFO队列来完成,同步队列的头结点是当前获取到同步状态的结点,获取同步状态state失败的线程,会被构造成一个结点(或共享式或独占式)加入到同步队列尾部(采用自旋CAS来保证此操作的线程安全),随后线程会阻塞;释放时唤醒头结点的后继结点,使其加入对同步状态的争夺中。
总结下获取锁的流程:
调用自定义同步器的tryAcquire()尝试直接去获取资源,如果成功则直接返回;
没成功,则addWaiter()将该线程加入等待队列的尾部,并标记为独占模式;addWaiter()的操作过程是首先尝试快速方式直接放到等待队列的队尾
acquireQueued()使线程在等待队列中休息,有机会时(轮到自己,会被unpark())会去尝试获取资源。获取到资源后才返回。如果在整个等待过程中被中断过,则返回true,否则返回false。
如果线程在等待过程中被中断过,它是不响应的。只是获取资源后才再进行自我中断selfInterrupt(),将中断补上。
在这里插入图片描述

AQS相关的并发类
CountDownLatch 用来解决一个线程等待多个线程的场景,旅游团团长必须等待所有游到齐才能出发去下一个景点;计数器不能循环使用(案例,通过两个线程池分别获取未对账订单和派送单,最后在主线程之中完成对账操作)
CyclicBarrier 用来解决一组线程之间相互等待,几个驴友之间不离不弃;计数器可以循环使用,同时也可以设置回调函数

Lock和Condition
Lock和Condition相比于JDK中synchronized的优势在于
1 能够响应中断
2 支持超时
3 支持非阻塞地获取锁 ,如果尝试获取锁失败,并不进入阻塞状态,而是直接返回
4 支持公平和非公平方式获取锁
我们可以通过condition的signal,await,signalAll,实现条件等待

Semaphore 可以控制指定数量的线程获取资源
核心是一个计数器 一个等待队列 和三个方法
init( ) down( ) up( )
信号量模型里面,down()、up() 这两个操作历史上最早称为 P 操作和V 操作,所以信号量模型也被称为 PV 原语。

ReadWriteLock
读读不互斥,读写互斥,写写互斥 适合于读多写少的场景
获取写锁的前提是读锁和写锁均未被占用
获取读锁的前提是没有其他线程占用写锁
ReadWriteLock 不允许锁的升级,只允许锁的降级,如果先持有读锁,随后再尝试获取写锁,那么线程将被永久阻塞;如果先持有写锁,在持有读锁,再释放写锁,此时线程将会依旧持有写锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值