当前位置:网站首页>并发编程第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
最后在这一步阻塞了线程
边栏推荐
- 2022杭电多校六 1006-Maex (树形DP)
- 2022牛客多校六 B-Eezie and Pie (dfs)
- 使用Mongoose populate实现多表关联存储与查询,内附完整代码
- 51nod 2882最短路 (树链剖分)
- 51nod2861 2-sat
- RecyclerView的多选模式
- Introduction to Qt (5) - file operation, hotkey and mouse reading (implementation of txt window)
- 风控建模一:好坏标签定义
- -Wl,--start-group ... -Wl,--end-group for resolving circular dependencies of several libraries
- (2022牛客多校四)N-Particle Arts(思维)
猜你喜欢
2021 RoboCom 世界机器人开发者大赛-本科组(决赛)7-4猛犸不上 Ban(最短路)
10 Spark on RDD Cache
(2022杭电多校四)1011-Link is as bear(思维+线性基)
考证必看 | PMP扫盲贴+PMP材料
2022牛客多校六 J-Number Game(简单推理)
Qt入门(四)——连续播放图片(两种定时器的运用)
(codeforce547)C-Mike and Foam(质因子+容斥原理)
(2022杭电多校六)1012-Loop(单调栈+思维)
(2022牛客多校五)B-Watches(二分)
(2022牛客多校二)L-Link with Level Editor I(动态规划)
随机推荐
跨域请求浏览器无法显示set-cookie,坑了我一晚上
mysql 高级知识【order by 排序优化】
(2022牛客多校二)L-Link with Level Editor I(动态规划)
神经网络学习笔记(1)
一命令删除所有指定进程
(2022牛客多校五)B-Watches(二分)
WeChat applet wx:for loop output example
2022杭电多校五 C - Slipper (dijkstra+虚拟结点)
(2022杭电多校六)1012-Loop(单调栈+思维)
makefile automatically compiles C files in directories and subdirectories
Modal dialog is used to implement the sign-in
05 Spark on 读取内部数据分区存储策略(源码角度分析)
循环神经网络实现股票预测
洛谷P4197 Peaks 线段树合并
Learning experience of bp neural network
从stm32移植ucos2的代码到GD32
【CUDA】version switch freely
postgresql源码学习(35)—— 检查点⑤-检查点中的XLog清理机制
Kubernetes web网站无法访问
stm32使用spi1在slave 模式下 dma 读取数据