相关栏目
新闻资讯 >>
合作媒体 >>
展会知识 >>
当前位置:首页 >

这都可以?(aqs有限公司)aqs原理,


AQS概述

AQS 是JUC并发包中ReentrantLock,ReentrantReadWriteLock,CountDownLatch,CyclicBarrier等类的底层实现。

AQS主要是维护了一个CLH阻塞队列(双向队列)这都可以?(aqs有限公司)aqs原理,(图1)

image.png

这个队列中保存的是没有获得锁的线程。

获取锁资源

线程A

ReentrantLock lock = new ReentrantLock(true); Condition condition = lock.newCondition(); try{ lock.lock(); //..... condition.await(); }finally{ lock.unlock(); }

具体过程如下:

1.有A,B两个线程去获取资源,A线程通过Lock方法获取锁资源。2.B线程接着去调用Lock方法想获取已经属于A的锁资源。3.B线程会因为获取锁失败(通过CAS操作对状态位进行标记来获取锁),被封装成Node节点放入到AQS CLH双向队列中4.调用LockSupport.park()将线程阻塞挂起。5.同理其他再想争用线程A锁的线程也会被加入CLH队列中,并被挂起。

condition

我们知道Lock和synchronized的一大区别就是Lock支持条件的,Lock和condition的关系是1:n的,即一个lock可以有多个条件

Lock lock = new ReentrantLock(); Condition condition1 = lock.newCondition(); Condition condition2 = lock.newCondition();
这都可以?(aqs有限公司)aqs原理,(图2)

image.png

条件阻塞

Lock和使用condition步骤如下:

1.线程A需要通过lock方法先获得lock锁。2.当线程A调用到condition.await()释放锁(通过CAS操作对状态进行标记)3.阻塞线程A4.线程A封装成node节点放入条件队列中(每个条件有自己的条件队列,和AQS的CLH队列无关)5.由于资源被释放,因此去AQS中唤起一个之前被阻塞挂起的线程。

条件释放

try { lock.lock(); ... condition.signal(); } finally { lock.unlock(); }
1.已经有线程A因为lock的条件被加入到条件队列,并且被挂起(但是不会将线程加入AQS阻塞队列,因为条件尚未满足)。同时线程A释放lock锁2.线程B获取lock锁3.线程B之行condition.signal将原本已经因为条件不满足加入到条件队列的线程B取出。并将线程B加入到AQS阻塞队列中4.当线程B之行unlock操作,阻塞队列中的线程A可以进行lock的资源争抢。

AQS概述已经讲完了,下篇介绍下AQS源码层面相关。

参考文章

5分钟入门AQS

注明:本文章来源于互联网,如侵权请联系客服删除!