当前位置:网站首页>并发编程第8篇,AQS源码解读
并发编程第8篇,AQS源码解读
2022-08-08 23:36:00 【进击的豆子】
public class AqsLock {
public static void main(String[] args) {
Lock lock = new ReentrantLock(true);
Thread t1 = new Thread("t1"){
@Override
public void run() {
lock.lock();
System.out.println("t1=========start");
long l1= System.currentTimeMillis();
for (int i= 0;i<500000;i++){
System.out.println("t1线程执行的业务代码"+i);
}
long l2= System.currentTimeMillis();
System.out.println("t1业务执行时间=="+(l2-l1));
System.out.println("t1=========end");
lock.unlock();
}
};
Thread t2 = new Thread("t2"){
@Override
public void run() {
lock.lock();
System.out.println("t2=========start");
lock.unlock();
}
};
t1.start();
t2.start();
}
}

当T1线程第一次执行lock的时候,它会执行下面的方法

其中的sync是一个继承的AQS抽象类

用的是模板方法,模板方法设计模式,内部提供公共业务方法:nonfairTryAcquire(非公平锁重试),tryRelease(释放锁次数每次调用减一),isHeldExclusively(头部线程是等于当前线程),newCondition(创建condition对象),getOwner(获取现在拥有锁的对象,如果state==0,则为空说明没有线程获取得锁重新竞争锁),getHoldCount(获得重入次数),isLocked(是否有线程获取锁),readObject。和抽象方法lock。

Sync有两个实现类一个公平锁,一个非公平锁,因为上面传的true所以构造函数走的是公平锁的的lock方法


最后还是调用到公平锁的 tryAcquire传过来的acquires=1,state没人修改过值默认为0,或者调用了tryRelease减为了0

hasQueuedPredecessors判断是否有头结点,下面这段代码有很多种情况,写的真的很牛逼
其中有情况:第一次,node结点还是没有初始化
情况2:AQS队列有数据,但是突然插入的线程还没存入队列和下一个节点一起竞争锁
这里因为是第一次进来线程队列没有初始化所以hasQueuedPredecessors返回false,然后取反执行compareAndSetState执行cas把state置为1并且当前线程为ownerThread返回true,下面的else if 是线程的重入性,

tryAcquire返回的是true取反为false就不用走下面把当前线程添加到同步队列的方法也再往上也意味着lock方法结束



因为t1和t2线程是差不多同时启动的,因为t1.start在t2.start前面一点点所以可能主线程在顺序执行的时候t2可能会比t1晚那么一点点,当t2调用到lock的时候

再走到tryAcquire的时候c=1,当前getExclusiveOwnerThread为t1线程,因为t1还在执行for循环里面的业务代码还没有释放锁

所以t2线程一定会执行这个方法

Node.EXCLUSIVE第一次初始为null





最后在这一步阻塞了线程

边栏推荐
猜你喜欢

51nod 2882最短路 (树链剖分)

(2022杭电多校六)1010-Planar graph(最小生成树)

linux环境安装mysql和使用中的常见问题

(2022杭电多校三)1011.Taxi(曼哈顿最值+二分)

Introduction to Qt (5) - file operation, hotkey and mouse reading (implementation of txt window)
![[PP-YOLOv2] Training a custom dataset](/img/f5/90fb1a4b6096f77755f566a6acbf0a.png)
[PP-YOLOv2] Training a custom dataset

Hi3516 use wifi module

2022牛客多校六 A-Array(构造+哈夫曼)
![[YOLOv5] 6.0 environment construction (updated from time to time)](/img/db/c363d76387c0770707dd9675d471c7.png)
[YOLOv5] 6.0 environment construction (updated from time to time)

牛客多校2 G League of Legends
随机推荐
关于vm虚拟机虚拟网络已禁用
WeChat applet error undefined Expecting 'STRING','NUMBER','NULL','TRUE','FALSE','{','[', got ]Solution
Introduction to Qt (5) - file operation, hotkey and mouse reading (implementation of txt window)
根據百度地图返回的地址,截取省,市,区
(2022杭电多校六)1012-Loop(单调栈+思维)
MES对接Simba实现展讯平台 IMEI 写号与耦合测试
时间对象的格式化
(2022牛客多校五)D-Birds in the tree(树形DP)
(newcoder 15079)无关(容斥原理)
不躺平,然后做到极致,就是最大的“安全感”
postgresql源码学习(35)—— 检查点⑤-检查点中的XLog清理机制
【深度学习】TensorFlow学习之路五:DNN防止过拟合的几种方法及TensorFlow实现
跨域请求浏览器无法显示set-cookie,坑了我一晚上
【深度学习】TensorFlow学习之路三:梯度消失\爆炸及解决办法
09 Spark on RDD 阶段划分
Tp5 in cache cache, storage cell phone text message authentication code
可以在易方达基金上买基金吗,安全吗
使用Mongoose populate实现多表关联存储与查询,内附完整代码
2022牛客多校六 J-Number Game(简单推理)
Binary tree level traversal and examples